CF1762F 题解
思路
发现若合法子序列的三个连续元素
显然单调不增和单调不降两种序列只会在
考虑怎么处理这个序列,发现对于
剩下的就只有
现在需要求的是每个数后面的
另外还需要注意所有的清空都需要清空每个
代码
#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
#define int long long
using namespace std;
const int N=5e5+10;
const int P=1e5;
int n,k,res,a[N],t[N],nxt[N],f[N];
set <int> pos;
vector <int> tp[N],tv;
struct bit
{
int b[N];
int lowbit(int x){return x&(-x);}
void add(int p,int x){for(;p<=P;p+=lowbit(p)) b[p]+=x;}
int query(int p){int tr=0; for(;p;p-=lowbit(p)) tr+=b[p]; return tr;}
}T;
void solv()
{
for(int i=1;i<=n;i++)
{
if(tp[a[i]].empty()) tv.push_back(a[i]);
tp[a[i]].push_back(i);
}
sort(tv.rbegin(),tv.rend()),pos.insert(n+1); int l=0;
for(int x:tv)
{
while(tv[l]>x+k)
{
for(int p:tp[tv[l]]) pos.erase(p);
l++;
}
sort(tp[x].rbegin(),tp[x].rend());
for(int p:tp[x]) nxt[p]=(*pos.lower_bound(p)),pos.insert(p);
}
for(int x:tv) tp[x].clear();
tv.clear(),pos.clear();
for(int i=n;i>=1;i--)
{
f[i]=1;
if(nxt[i]!=n+1) f[i]=f[nxt[i]]+T.query(a[nxt[i]]-1)-T.query(a[i]-1)+1;
T.add(a[i],1),res+=f[i];
}
for(int i=1;i<=n;i++) T.add(a[i],-1);
}
void sol()
{
cin>>n>>k,res=0;
for(int i=1;i<=n;i++) cin>>a[i],t[a[i]]++,res-=t[a[i]];
solv();
for(int i=1;i<=n;i++) t[a[i]]--,a[i]=P-a[i]+1;
solv(),cout<<res<<'\n';
}
signed main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int TT; cin>>TT;
while(TT--) sol();
return 0;
}