题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6794
题目大意:给定一个长度为n的数列,一个数字p,每次可任意选择两个相邻数进行合并(最多合并n-1次 然而这并不重要hh),求合并过程中的数列中,使得其%p为0的数的个数。//表达能力好烂 草(笑)
主要思路:首先读入,每个都去%p。想到前缀和,但不用一上来就求完全部的。因为每当从第i个开始的k个数的sum为0,下标大于 i+k 的前缀和在此之前是不用求出的。因而轻轻松松,只要用一个sum,我们一边读入,一边就逐步计算前缀和。而当加入data[i]后的 sum == 0,则res++,清零sum重新计算由下一位开始的前缀和。这里推荐使用map,速度很快还能以数组形式访问。直接一个.clear就可,不用vis数组的memset。否则你会尝到疯狂TLE的美味感jio。
(本段看起来比较憨憨,给初学者或者像我这样的憨憨看就很合适)))doge << 1
*转载请注明本博客链接 谢谢
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<map> using namespace std; const int maxn = 1e5+10; int n, p, res; int data[maxn]; map<int, int> m;//map是真滴快 int main(){ int T;scanf("%d",&T); while(T--){ res = 0; m[0] = 1; scanf("%d %d",&n,&p); int sum = 0; for(int i = 1 ; i <= n ; i++){ scanf("%d",&data[i]); data[i] %= p; sum = (sum + data[i]) % p; if(m[sum]){ res++; sum = 0; m.clear(); m[0] = 1;//sum == 0 时,此时计算的前缀和恰好组成p的整数倍 }else{ m[sum]++; } } printf("%d ",res); } return 0; }