【问题描述】
给你一个长度为N的正整数序列,如果一个连续的子序列,子序列的和能够被K整除,那么就视此子序列合法,求原序列包括多少个合法的连续子序列?
对于一个长度为8的序列,K=4的情况:2, 1, 2, 1, 1, 2, 1, 2 。它的答案为6,子序列是位置1->位置8,2->4,2->7,3->5,4->6,5->7。
【输入格式】
第一行:T,表示数据组数
对于每组数据:
第一行:2个数,K,N
第二行:N个数,表示这个序列
【输出格式】
共T行,每行一个数表示答案
【输入样例】
2
7 3
1 2 3
4 8
2 1 2 1 1 2 1 2
【输出样例】
0
6
【数据规模】
100%数据满足
1<=T<=20
1<=N<=50000
1<=K<=1000000
序列的每个数<=1000000000
30%数据满足
1<=T<=10
1<=N,K<=1000
#include<bits/stdc++.h> using namespace std; int a,tot,s[1000005];//s[i]用来存1~m前缀和 mod k余i的个数 int n,t,k; long long ans; int main() {freopen("seq.in","r",stdin); freopen("seq.out","w",stdout); scanf("%d",&t); for(int iii=1;iii<=t;iii++) {ans=0,tot=0; memset(s,0,sizeof(s)); s[0]=1; scanf("%d%d",&k,&n); for(int i=1;i<=n;i++) {scanf("%d",&a);tot=(tot+a)%k;s[tot]++;}//计算s for(int i=0;i<k;i++) if(s[i]) ans+=(s[i]*(s[i]-1)/2); //由于两个s[i]代表的i相减为0,两个对应位置间(左开右闭)的序列合法 //所以答案为每两个相同的s可确定一个合法答案,n个相同的s确定n*(n-1)/2个合法答案 //最后把每个s[i]得出的答案相加就是总答案 printf("%lld ",ans); } return 0; }