蓝桥集训之K倍区间
-
核心思想:前缀和+哈希表
- 暴力o(N3) : 三层循环找差值为k的区间
- 前缀和优化o(N2) : 前缀和减少一层循环
- 哈希表优化o(N) : 只剩一层循环
- 余数范围0 ~ R–1
- 每次将i之前的与当前s[i]余数相同的区间个数 加上
- 因为s[j]-s[i]求区间和时 余数相同会消掉 只剩下k的倍数
-
#include<iostream> using namespace std; typedef long long LL; const int N = 100010; LL a[N],s[N],cnt[N]; int n,k; int main() { cin>>n>>k; for(int i=1;i<=n;i++) { cin>>a[i]; s[i] = s[i-1] + a[i]; } LL res=0; cnt[0] = 1; for(int i=1;i<=n;i++) { res += cnt[s[i] % k]; cnt[s[i]%k] ++; } cout<<res; }