求助
查看原帖
求助
841638
Igunareo楼主2024/10/3 20:20
#include<bits/stdc++.h>
#define int long long
using namespace std;
int dp[500005][5];
int x[500005],cnt[500005],block[500005];
struct Edge{int summ,val;}y[4000005];
void clear(int now,int l,int r,int a,int p){
	y[now].summ=y[now].val=0;
	if(l==r&&l==a)return;
	int mid=(l+r)/2;
	if(a<=mid)clear(now*2,l,mid,a,p);
	else clear(now*2+1,mid+1,r,a,p);
	return;
}
void up(int now,int l,int r,int a,int p){
	if(l==r&&l==a){
		y[now].summ=1;
		y[now].val=p;
		return;
	}
	int mid=(l+r)/2;
	if(a<=mid)up(now*2,l,mid,a,p);
	else up(now*2+1,mid+1,r,a,p);
	y[now].summ=y[now*2].summ+y[now*2+1].summ;
	return;
}
int down1(int now,int l,int r,int a){
	if(a<=0)return 0;
	if(a>100000)return y[now].summ;
	if(l==r&&l==a)return y[now].summ;
	int mid=(l+r)/2;
	if(a<=mid)return down1(now*2,l,mid,a);
	else return down1(now*2+1,mid+1,r,a)+y[now*2].summ;
}
int down2(int now,int l,int r,int a){
	if(!a)return 0; 
	if(a>y[now].summ)return 0;
	if(l==r&&a==1)return y[now].val;
	int mid=(l+r)/2;
	if(y[now*2].summ>=a)return down2(now*2,l,mid,a);
	else return down2(now*2+1,mid+1,r,a-y[now*2].summ);
}
signed main(){
	int T;
	scanf("%lld",&T);
	while(T--){
		int n,k;
		scanf("%lld%lld",&n,&k);
		for(int i=1;i<=n;i++){
			scanf("%lld",&x[i]);
			block[i]=(x[i]-1)/(k+1);
		}
		for(int i=1;i<=n;i++){
			cnt[block[i]]++;
			dp[i][0]=dp[i][1]=dp[i][2]=cnt[block[i]];
			int a=down2(1,1,100000,down1(1,1,100000,x[i]-k-1)+1);
			int b=down2(1,1,100000,down1(1,1,100000,x[i]+k));
			//cout<<i<<':'<<a<<' '<<b<<' ';
			if(a&&x[i]>=x[a]){
				if(block[a]==block[i])dp[i][1]=dp[i][0]+dp[a][1]-dp[a][0];
				else dp[i][1]=dp[a][1]+dp[i][0];
				//cout<<1<<' ';
			}
			if(b&&x[i]<=x[b]){
				if(block[b]==block[i])dp[i][2]=dp[b][2]+dp[i][0]-dp[b][0];
				else dp[i][2]=dp[b][2]+dp[i][0];
				//cout<<1<<' ';
			}
			//cout<<endl;
			up(1,1,100000,x[i],i);
		}
		int ans=0;
		for(int i=1;i<=n;i++)ans+=dp[i][1]+dp[i][2]-dp[i][0];
		printf("%lld\n",ans);
		/*for(int i=1;i<=n;i++)cout<<dp[i][0]<<' ';
		cout<<endl;
		for(int i=1;i<=n;i++)cout<<dp[i][1]<<' ';
		cout<<endl;
		for(int i=1;i<=n;i++)cout<<dp[i][2]<<' ';
		cout<<endl;*/
		for(int i=1;i<=n;i++)dp[i][0]=dp[i][1]=dp[i][2]=cnt[block[i]]=0;
		for(int i=1;i<=n;i++)clear(1,1,100000,x[i],i);
	}
	return 0;
}
2024/10/3 20:20
加载中...