显然通过尺取法可以找到每次以j为结尾,包含j的区间,往左延伸,最左能到i (i<=j)
于是以j为结尾的区间有(j-i+1)个
累加即可
#include<stdio.h>
#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define MEM(a,x) memset(a,x,sizeof(a))
#define lowbit(x) ((x)&-(x))
using namespace std;
const int N = 2e5+5;
int a[N];
map<int,int>mp;
void eraseAi(int i){
auto it=mp.find(a[i]);
--it->second;
if(it->second==0){
mp.erase(it);
}
}
ll slove(int n,int k){
mp.clear();
int i=0;
mp[a[i]]=1;
ll ans=1;
for(int j=1;j<n;++j){
mp[a[j]]+=1;
while((--mp.end())->first-mp.begin()->first>k){
eraseAi(i);
++i;
}
ans+=(j-i+1);
}
return ans;
}
int main()
{
//freopen("/home/lu/code/r.txt","r",stdin);
//freopen("/home/lu/code/w1.txt","w",stdout);
int n,k;
while(~scanf("%d%d",&n,&k)){
for(int i=0;i<n;++i){
scanf("%d",&a[i]);
}
printf("%lld\n",slove(n,k));
}
return 0;
}
尺取法求区间数量

4906

被折叠的 条评论
为什么被折叠?



