题目描述
有 N N N 个盒子排成一排,第 i i i 个盒子里有 A i A_i Ai 个糖果。你需要从一些连续的盒子里取出糖果,分给 M M M 个小朋友,使得每个小朋友得到的糖果数量相等。求有多少种取法满足以下两个条件:
- 取出的盒子数为 r − l + 1 r-l+1 r−l+1,其中 1 ≤ l ≤ r ≤ N 1\le l\le r\le N 1≤l≤r≤N。
输入格式
- 第一行包含两个整数 N N N 和 M M M。
- 第二行包含 N N N 个整数 A 1 , A 2 , … , A N A_1,A_2,\dots,A_N A1,A2,…,AN。
输出格式
输出一个整数,表示满足条件的取法数。
数据范围
- 1 ≤ N ≤ 1 0 5 1\le N\le 10^5 1≤N≤105,
- 1 ≤ M ≤ 10 1\le M\le 10 1≤M≤10,
- 1 ≤ A i ≤ 1 0 9 1\le A_i\le 10^9 1≤Ai≤109。
输入样例1:
3 2
4 1 5
输出样例1:
3
样例1解释:
符合条件的取法有 ( 1 , 3 ) , ( 2 , 3 ) , ( 3 , 3 ) (1,3),(2,3),(3,3) (1,3),(2,3),(3,3)。
输入样例2:
13 17
29 7 5 7 9 51 7 13 8 55 42 9 81
输出样例2:
6
输入样例3:
10 400000000
1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000
输出样例3:
25
这题先求前缀和,然后再mod n。
思想很简单,但是m的数据很大,所以还需要一个容器map,或者是hash。
如果不会map的就看看作者之前发的文章,里面有详解。
不多说了,看代码。
#include<bits/stdc++.h>
using namespace std;
map<long long ,long long>cnt;//定义map
long long n,m,i,a[1000001],q[1000001],ans;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
q[i]=(q[i-1]+a[i])%m;//求前缀和
}
cnt[0]=1;
for(int i=1;i<=n;i++){
ans+=cnt[q[i]];
cnt[q[i]]++;
}
cout<<ans;
return 0;
}
就这么多,记得点赞哟。