蓝桥杯复习之前缀和

题目链接:https://www.luogu.com.cn/problem/P8649

思路:
    看到区间和,第一反应肯定是前缀和,我们求出前缀和后对前缀和数组每一个值模k,然后对一个数组的值查看前面有几个相同的,举个例子:

    样例中前缀和数组a取模后为:1    1    0    0    1

    下标依次为1 2 3 4 5

    当题目所求子序列以a5结尾时,已知a5=1且a5前面与a5相同的值有2个,则以a5结尾可以获得2个满足题目要求的区间
    
    如果以a3结尾则是一个,因为实际上有一个a0=0。
 

#include<bits/stdc++.h>

using namespace std;

using ll = long long;
const ll N = 3e5 + 5;
const ll mod = 1e9 + 7;
int gcd(int a, int b) {
	return b ? gcd(b, a % b) : a;
}

void solve() {
	int n; cin >> n;
	ll k; cin >> k;
	vector<ll>a(n + 1);
	vector<ll>pre(n + 1);
	vector<ll>cnt(n + 1);

	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		pre[i] = pre[i - 1] + a[i];
	}

	ll ans = 0;
	cnt[0] = 1;

	for (int i = 1; i <= n; i++) {
		ans += cnt[pre[i] % k];
		cnt[pre[i] % k]++;
	}
	cout << ans << '\n';
}
		

signed main() {

	ios::sync_with_stdio(false);
	cin.tie(0);
	std::cout.tie(0);

	int t1 = 1;
	//cin >> t1;
	while (t1--)
		solve();

	return 0;
}

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值