[蓝桥杯 2017 省 B] k 倍区间
题目描述
给定一个长度为 NNN 的数列,A1,A2,⋯ANA_1,A_2, \cdots A_NA1,A2,⋯AN,如果其中一段连续的子序列 Ai,Ai+1,⋯Aj(i≤j)A_i,A_{i+1}, \cdots A_j(i \le j)Ai,Ai+1,⋯Aj(i≤j) 之和是 KKK 的倍数,我们就称这个区间 [i,j][i,j][i,j] 是 KKK 倍区间。
你能求出数列中总共有多少个 KKK 倍区间吗?
输入格式
第一行包含两个整数 NNN 和 KKK(1≤N,K≤105)(1 \le N,K \le 10^5)(1≤N,K≤105)。
以下 NNN 行每行包含一个整数 AiA_iAi(1≤Ai≤105)(1 \le A_i \le 10^5)(1≤Ai≤105)。
输出格式
输出一个整数,代表 KKK 倍区间的数目。
样例 #1
样例输入 #1
5 2
1
2
3
4
5
样例输出 #1
6
提示
时限 2 秒, 256M。蓝桥杯 2017 年第八届
两秒的时限已经很水了,不过记得开long long。
看到区间就一定要第一时间想到前缀和或差分,这题很水,在前缀和模板上对k取个模然后循环遍历就行了。
Code
#include<bits/stdc++.h>
using namespace std;
long long c[100002]={1};//预处理
int main(){
long long n,k;
cin>>n>>k;
long long a,sum=0;
for(long long i=1;i<=n;i++){
cin>>a;
sum=(sum+a)%k;//计算前缀和
c[sum]++;//储存前缀和
}
sum=0;
for(long long i=0; i<k; i++){
sum+=c[i]*(c[i]-1)/2;//储存答案
}
cout<<sum;
return 0;
}
446

被折叠的 条评论
为什么被折叠?



