AtCoder Beginner Contest 105 D Candy Distribution
Problem Statement
There are N boxes arranged in a row from left to right. The i-th box from the left contains *A**i* candies.
You will take out the candies from some consecutive boxes and distribute them evenly to M children.
Such being the case, find the number of the pairs (l,r) that satisfy the following:
- l and r are both integers and satisfy 1≤l≤r≤N.
- Al+Al+1+…+*A**r* is a multiple of M.
Constraints
- All values in input are integers.
- 1≤N≤105
- 2≤M≤109
- 1≤*A**i*≤109
Input
Input is given from Standard Input in the following format:
N M
A1 A2 … AN
Output
Print the number of the pairs (l,r) that satisfy the conditions.
Note that the number may not fit into a 32-bit integer type.
Sample Input 1
3 2
4 1 5
Sample Output 1
3
The sum Al+Al+1+…+*A**r* for each pair (l,r) is as follows:
- Sum for (1,1): 4
- Sum for (1,2): 5
- Sum for (1,3): 10
- Sum for (2,2): 1
- Sum for (2,3): 6
- Sum for (3,3): 5
Among these, three are multiples of 2.
Sample Input 2
13 17
29 7 5 7 9 51 7 13 8 55 42 9 81
Sample Output 2
6
Sample Input 3
10 400000000
1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000
Sample Output 3
25
题解
题意
N个盒子,每个盒子内的糖果数有Ai个,问区间(l,r)范围内,糖果数总和为M倍数的区间有几个?
思路
首先,按照Ai%M的数目进行统计,得到在Ai%M的组数。然后可以选取区间,对于%M为0的组数,直接添加组数。对于%M为其他值的组数,加上组数X(组数-1)/2。最终得到数目。
注意,由于M非常大而且有很多空值,所以数组方法不现实,最开始在这里坑了一次,后来转向map才写明白,耽误了一部分时间。
代码
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
#define REP(i,n) for(int i=0;i<(n);i++)
const int MAXN = 1e5+10;
ll A[MAXN];
ll sum[MAXN];
map<int,int>m1;
int main(){
ll N,M;
scanf("%d %d",&N,&M);
for(int i=0;i<N;i++){
scanf("%lld",&A[i]);
}
memset(sum,0,sizeof(sum));
sum[0] = A[0];
m1.insert(make_pair(A[0]%M,1));
for(int i=1;i<N;i++){
sum[i] = sum[i-1]+A[i];
int c = sum[i]%M;
map<int,int>::iterator iter = m1.find(c);
ll a=0;
ll b=0;
if(iter!=m1.end()){
a = iter->first;
b = iter->second;
m1.erase(iter);
m1.insert(make_pair(a,b+1));
}else{
a = c;
m1.insert(make_pair(a,1));
}
}
ll ans = 0;
map<int,int>::iterator iter;
for(iter=m1.begin();iter!=m1.end();iter++){
ll a= iter->first;
ll b= iter->second;
if(a==0) ans+=b;
ans += b*(b-1)/2;
}
printf("%lld\n",ans);
return 0;
}