点击跳转例题
思路:
先想暴力,如果利用前缀和,但是还是n平方的复杂度,所以我们要优化,我们发现任意两个前缀和在对k取模的时候,如果两个前缀和模k的余数相同,那么两个前缀和的差一定是k的倍数,那么我们只需要记录模 k 所有情况下,所有余数的个数即可,那后用组合数学的思想记录答案。
代码:
#include <bits/stdc++.h> #define int long long //(有超时风险) #define PII pair<int,int> #define endl '\n' #define LL __int128 using namespace std; const int N=2e5+10,M=1e3+10,mod=998244353,INF=0x3f3f3f3f; int a[N],b[N],c[N],pre[N]; signed main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int n,k;cin>>n>>k; for(int i=1;i<=n;i++) cin>>a[i]; //mp记录模k的余数的个数。 map<int,int>mp; for(int i=1;i<=n;i++) { pre[i]=(pre[i-1]+a[i])%k; mp[pre[i]]++; } int ans=0; for(auto i:mp) { if(i.first==0) ans+=(i.second)*(i.second+1)/2; else ans+=(i.second-1)*(i.second)/2; } cout<<ans<<endl; return 0; }
P8649 [蓝桥杯 2017 省 B] k 倍区间--2024蓝桥杯冲刺省一
最新推荐文章于 2024-05-17 09:49:17 发布