题意:给一个长为
由题知,题目要我们求满足以下条件的个数:
简单化简一下便可轻松的得到以下式子:
所以我们新建立一个数组
可以选择 multiset 或 map 两种方式维护。
Multiset( pts)
直接每次加上 count 值再 insert 即可。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=2e6+100;
int n,k,a[maxn],ans;
long long num[maxn],sum[maxn];
multiset<int> p;
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
num[i]=(sum[i]-i+k)%k;
}
p.insert(0);
for(int i=1;i<=n;i++)
{
if(i>=k)
p.erase(p.find(num[i-k]));
ans+=p.count(num[i]);
p.insert(num[i]);
}
printf("%d",ans);
return 0;
}
Map( pts)
直接先预处理好 map[i]++,map[i-k]--。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;
const int maxn=2e6+100;
long long n,k,a[maxn],ans;
long long num[maxn],sum[maxn];
map<long long,int> p;
int main()
{
scanf("%lld%lld",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
sum[i]=sum[i-1]+a[i];
num[i]=(sum[i]-i+k)%k;
}
int m=min(k-1,n);
for(int i=0;i<=m;i++)
{
ans+=p[num[i]];
p[num[i]]++;
}
for(int i=m+1;i<=n;i++)
{
p[num[i-k]]--;
ans+=p[num[i]];
p[num[i]]++;
}
printf("%lld",ans);
return 0;
}