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 Ai 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+…+Ar is a multiple of M.
Constraints
All values in input are integers.
1≤N≤105
2≤M≤109
1≤Ai≤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+…+Ar 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
【感想】:
这个题就是蓝桥杯的原题叫作:K倍区间。
这个题就是对取模用处的最好的诠释了。
真的不错,可以对一个式子进行推导计算得到了。
【推导】:
题目给的N虽然是1e5,但是我们要枚举所有的区间,起码是N^2.
所以我们要思考一波。
首先我们知道表达一个区域『L,R』一定是用前缀和来处理对吧。
这个前缀和:sum[ R ]-sum[ L-1 ]。
我们想求一下K的倍数对吧。不就是对这个区域取模。
(Sum[ R ]- Sum[ L-1 ])%K==0;
但是我们知道,Sum[ R ]%K -Sum [ L - 1 ] %K==0 这个式子是等价对吧。
那么我们找的就是 (Sum[ L ]%K==0)或者(Sum[ R ] - Sum [ L-1 ])%K==0.
我们在任意一个 Sum【D】任意取两个作为两个端点就是,组合数:
贴上代码给大家理解一下吧。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1e6+10;
ll a[N],sum[N];
map<ll, int>mp;
int main()
{
ll n,k;
scanf("%lld%lld",&n,&k);
set<ll>S;
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
sum[i]=(a[i]+sum[i-1])%k;
mp[sum[i]]++;
S.insert(sum[i]);
}
/*for(int i=1;i<=n;i++){
printf("%d\n",sum[i]);
}*/
ll ans=mp[0];
set<ll> ::iterator it=S.begin();
for( ; it!=S.end();it++){
int cur=*it;
ll t=mp[cur];
ans+=(t*(t-1))/2;
}
printf("%lld\n",ans);
return 0;
}