[思维] NamomoCamp Daily 7

NamomoCamp Daily 7

代码源oj网址http://oj.daimayuan.top/course/10/problem/466

题解:

先求前缀和,可以发现最终要我们找的就是 ( S r − S l − 1 ) % k = r − l + 1 (S_r-S_{l-1})\%k=r-l+1 (SrSl1)%k=rl+1的个数。移项一下,就能将式子变成 ( S r − r ) % k = ( S l − 1 − ( l − 1 ) ) % k (S_r-r)\%k=(S_{l-1}-(l-1))\%k (Srr)%k=(Sl1(l1))%k的个数了。我们可以将每个 S i − i S_i-i Sii用map来保存个数,每次统计当前的 S i − i S_i-i Sii出现的个数即可。

注意, [ l , r ] [l,r] [l,r]的区间长度不会超过 k k k,如果等于 k k k那么求模会等于0。而且通过 r − l + 1 < k r-l+1<k rl+1<k可以求出 l > r − k + 1 l>r-k+1 l>rk+1,也就是区间长度固定不变,当一个 S l − l + 1 S_l-l+1 Sll+1对后续结果没有贡献后,我们可以将其删除。

代码:

代码源
// Good Good Study, Day Day AC.
#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <cstring>
#include <math.h>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <map>
#include <algorithm> 
#include <unordered_map>
#include <unordered_set>
#define ffor(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define rrep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(v,s) memset(v,s,sizeof(v))
#define IOS ios::sync_with_stdio(false),cin.tie(0)
#define ll long long
#define INF 0x7f7f7f7f7f7f7f7f
#define inf 0x7f7f7f7f
#define PII pair<int,int>
#define int long long

using namespace std;

const int N = 2e5 + 5;
int n, T, k;
int s[N];
map<int, int> m;

void ready()
{
	IOS;
	cin >> n >> k;
	ffor(i, 1, n) cin >> s[i];
	ffor(i, 1, n) s[i] += s[i - 1];
	ffor(i, 1, n) s[i] = (s[i] - i + k) % k;
}


void work()
{
	m[0]++;
	int ans = 0;
	ffor(r, 1, n) {
		if (r >= k) {
			m[s[r-k]]--; 
		}
		ans += m[s[r]];
		m[s[r]]++;
	}
	cout << ans;
}

signed main()
{
	ready();
	work();
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值