AtCoder Beginner Contest 105 D - Candy Distribution

题目描述

给定长度为 n 的数组,求有多少个区间满足区间和是给定数 m 的倍数

既然要是 m 的倍数,也就是 % m 之后的结果应该是 0

S u m 表示 % m 后的前缀和,如果当前 S u m 的值出现了多次说明之前也存在区间和在 % m 是当前这个 S u m 值。

这就意味着有两个从数组开头开始的区间他们的区间和再 % m 之后结果一样,与之对应的就是出现了一个区间满足了题意。

举个栗子。

[ 1 , a ] 这个区间的区间和在 % m 之后的结果为 S u m

[ 1 , b ] ( a < b ) 这个区间的区间和 % m 之后的结果也是 S u m

说明区间 [ a + 1 , b ] 这个区间的区间和在 % m 之后的结果就为 0 了,就满足题意。

于是我们只需要求出每次的 S u m ,并且记录之前 S u m 出现的次数即可。

#include <bits/stdc++.h>
#define LL long long
using namespace std;
map<LL,LL>Map;
LL N,M,Sum,Ans;
int main(){
    LL I,J,K;
    scanf("%lld%lld",&N,&M);
    Map[0]++;
    for(I=1;I<=N;I++){
        LL Num;
        scanf("%lld",&Num);
        Sum=(Num+Sum)%M;Ans+=Map[Sum]++;
    } 
    printf("%lld",Ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yanzhenhuai/article/details/81604638