hdu6794 Tokitsuka and Multiple // map&前缀和

题目链接: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;
} 
原文地址:https://www.cnblogs.com/ecustlegendn324/p/13449356.html