方法一:模拟暴力(20分)
| #include<bits/stdc++.h> |
| using namespace std; |
| const int max_n=100010; |
| int n, k, a[max_n]; |
| long long ans, s; |
| int main() |
| { |
| cin>>n>>k; |
| for(int i=1; i<=n; i++)cin>>a[i]; |
| for(int i=1; i<=n; i++){ |
| s=0; |
| for(int j=i; j<=n; j++){ |
| s=(s+a[j])%k; |
| if(s==0) |
| ans++; |
| } |
| } |
| cout<<ans; |
| return 0; |
| } |
方法二:前缀和

- 图中的第一排[1, 2, 5, 4, 3]是A数组。绿色的第二排是前缀和,天蓝色的第三排是前缀和%K之后的结果,这里我们假设K=2。
- 我们之前的算法,实际上就是在第三排的数组里,找两个相等的值。每一对相等的值,都对应着一个K倍区间。比如第三排有3个0,第一个0和第二个0,对应[1, 2, 5]这个区间;第一个和第三个0,对应[1, 2, 5, 4]这个区间;第二个和第三个0,对应[4]这个区间。
- 所以我们已知第三排数组有3个0和3个1的情况下,可以直接用组合数求出来K倍区间的数目:C(3,2)+C(3, 2)=6。C(3, 2)是指从3个物品里取出2个来的组合数。因为有3个0和3个1,所以答案就是C(3, 2)+C(3, 2)。
| #include<bits/stdc++.h> |
| using namespace std; |
| const int max_n=100010; |
| int n, k, a[max_n]; |
| long long s[max_n]; |
| long long ans, cnt[max_n]; |
| int main() |
| { |
| cin>>n>>k; |
| for(int i=1; i<=n; i++)cin>>a[i]; |
| cnt[0]=1; |
| |
| |
| for(int i=1; i<=n; i++){ |
| s[i] = (s[i-1] + a[i])%k; |
| cnt[s[i]]++; |
| |
| } |
| for(int i=0; i<k; i++) |
| ans += cnt[i]*(cnt[i]-1)/2; |
| |
| cout<<ans; |
| return 0; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2019-02-13 C++手写快读详解(快速读入数字)