給定一個長度為 N 的數列,A1,A2,…AN,如果其中一段連續的子序列 Ai,Ai+1,…Aj 之和是 K 的倍數,我們就稱這個區間 [i,j] 是 K 倍區間。
你能求出數列中總共有多少個 K 倍區間嗎?
輸入格式
第一行包含兩個整數 N 和 K。
以下 N 行每行包含一個整數 Ai。
輸出格式
輸出一個整數,代表 K 倍區間的數目。
資料範圍
1≤N,K≤100000,1≤Ai≤100000
輸入樣例:
5 2
1
2
3
4
5
輸出樣例:
6
題解:
- 先求字首和
- 對字首和s[i] 取餘, 餘數相同的字首和 互相相減是 k 的倍數
(ps : 如果餘數相同的個數是4, 那麼 答案應該加上 3 + 2 + 1; 相同的個數是 3 的話, 應該加上 2 + 1, 還不懂的話看下圖) - 區間中只有一個元素的也符合題意
下圖模擬的是樣例
#include <bits/stdc++.h>
#define int long long // 會爆 int
using namespace std;
const int N = 1e5 + 10;
int a[N], b[N];
signed main()
{
int n, k; cin >> n >> k;
int sum = 0;
for (int i = 1; i <= n; i ++)
{
cin >> a[i]; a[i] += a[i - 1]; // 求字首和
}
for (int i = 1; i <= n; i ++)
{ // 👇 圖解
if (b[a[i] % k] != 0) sum += b[a[i] % k];
b[a[i] % k] ++;
}
cout << sum + b[0] << endl; // 餘數是0的代表自己是一個區間, 符合題意, 所有 最終答案要加上b[0]
return 0;
}
覺得寫的不錯的話, 點個贊吧~