P8649 [蓝桥杯 2017 省 B] k 倍区间

文章讲述了如何使用前缀和和模运算解决一个经典问题,即找出给定整数数组中满足特定条件(前缀和对k取模相等)的区间数量。通过统计每个余数出现的次数并应用组合公式计算答案。
摘要由CSDN通过智能技术生成

P8649 [蓝桥杯 2017 省 B] k 倍区间

题目链接

思路

这题很经典,首先用前缀和维护,若区间 [ l , r ] [l,r] [l,r]符合条件,则 s l − 1 ≡ s r ( m o d k ) s_{l-1}\equiv s_r(mod k) sl1sr(modk),故对于前缀和的余数,若某个余数出现了 x x x次,则可在这 x x x个坐标中任选两个作为边界即可,即为 C x 2 C_{x}^{2} Cx2,若余数为零,则单个数也符合,最后在加上去

代码

#include <iostream>
#include <map>
#define int long long
using namespace std;

map <int, int> mp; //记录每个余数出现个数的数组

signed main()
{
	int n, k, ans = 0;
	cin >> n >> k;
	int cnt = 0;
	for(int i = 1;i <= n;i++)
	{
		int x;
		cin >> x;
		ans += (x % k); //计算前缀和
		mp[ans % k]++; //前缀和模 k
		ans %= k;
	}
	for(int i = 0;i < k;i++) cnt += (mp[i] * (mp[i] - 1)) / 2; //根据上述公式计算答案
	cout << cnt + mp[0] << endl; //将单个的加上去
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值