2017藍橋杯省賽第十題:k倍區間

Harris-H發表於2020-10-16

2017藍橋杯省賽第十題:k倍區間

給定一個長度為N的數列,A1, A2, … AN,如果其中一段連續的子序列Ai, Ai+1, … Aj(i <= j)之和是K的倍數,我們就稱這個區間[i, j]是K倍區間。

你能求出數列中總共有多少個K倍區間嗎?

輸入

第一行包含兩個整數N和K。(1 <= N, K <= 100000)
以下N行每行包含一個整數Ai。(1 <= Ai <= 100000)

輸出

輸出一個整數,代表K倍區間的數目。

例如,
輸入:

5 2
1  
2  
3  
4  
5  

輸出:

6

思路:字首和加列舉列舉右區間的貢獻即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int sum[N],cnt[N],n,k;
ll ans;
int main(){
	scanf("%d%d",&n,&k),cnt[0]=1;
	for(int i=1;i<=n;i++){
		scanf("%d",&sum[i]),sum[i]=(sum[i-1]+sum[i])%k;
		ans+=cnt[sum[i]];
		cnt[sum[i]]++;
	}
	printf("%lld\n",ans);
	return 0;
}

做完一個題就要思考一下:遇到這種型別的題,我們該往那哪個方向去考慮呢?

像這樣有關區間和的問題,我們第一時間就要想到字首和思想,因為字首和可以求出任意區間和,而對於統計區間個數的問題,我們通常採用列舉每個區間端點的貢獻(有可能是左端點,有可能是右端點),然後對所有區間貢獻求和即可。

而這一題,恰好利用兩個不同字首和 m o d   k mod\ k mod k後相等,則相減 m o d   k mod\ k mod k就等於0 的思想來統計個數,此外我們需要注意的是此題的正確性是因為 a i > 0 a_i>0 ai>0,如果有 a i = 0 a_i=0 ai=0的情況則需要討論,因為 0 ( m o d k ) = 0 0\pmod{k}=0 0(modk)=0

相關文章