https://vjudge.net/problem/AtCoder-4240
题意: 求所有区间中能够被 m 整除的有几个?
思路:根据同余定理,(a-b)%m=a%m-b%m, 显然要用到前缀和
分析:用 前缀和 处理区间问题,并且利用取模的特殊性质:如果余数相等,那么两个数相减就是整除的数,这刚好和前缀和的求区间和对应上了。
注意:不可能用数组来记录1E9种余数,所以要用 map ,一共只有1e5个数,最多只有1e5个值,用map把余数和个数对应起来。
且当位置i的前缀和可以被m除尽时,是可以以第一项为起点的。这种情况会被忽略,所以要在结果中补上。
#include <bits/stdc++.h> using namespace std; map<long long ,long long> mp; const int maxn = 2e5; int n,m; long long a[maxn]; long long pre[maxn]; long long cnt[maxn]; int main() { ios::sync_with_stdio(false); cin.tie(0); cin>>n>>m; for(int i=1; i<=n; i++){ cin>>a[i]; pre[i] = pre[i-1]+a[i]; } long long ans=0; for(int i=1; i<=n; i++){ ans += mp[pre[i]%m]; //cout<<pre[i]%m<<endl; //ans += cnt[ pre[i]%m ]; if( pre[i]%m==0 ) ans++; mp[ pre[i]%m ]++; //cnt[ pre[i]%m ]++; } cout<<ans<<endl; }