Splay60分TLE悬关求调
查看原帖
Splay60分TLE悬关求调
366468
_Z_Y_X_SWS楼主2023/9/20 19:41
#include <bits/stdc++.h>
using namespace std;
struct SPLAY{
	long long fa,ch[2],cnt,val,size;
}t[100005];
const long long mod=1000000;
long long root,tot,num,ans;
long long abss(long long k){
	return k<0?-k:k;
}
void maintain(long long x){
	t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+t[x].cnt;
}
void clear (long long x){
	t[x].ch[0]=t[x].ch[1]=t[x].cnt=t[x].size=t[x].fa=t[x].val=0;
}
bool get (long long x){
	return x==t[t[x].fa].ch[1];
}
void rotate (long long x){//旋转
	long long f=t[x].fa,z=t[f].fa,o=get(x);
	t[f].ch[o]=t[x].ch[o^1];
	if (t[x].ch[o^1]){
		t[t[x].ch[o^1]].fa=f;
	}
	t[x].ch[o^1]=f;
	t[f].fa=x;
	t[x].fa=z;
	if (z){
		t[z].ch[f==t[z].ch[1]]=x;
	}
	maintain (f);
	maintain(x);
}
void splay (long long x){//把x旋转到根
	for (long long f=t[x].fa;f!=0;f=t[x].fa){
		if (t[f].fa){
			rotate(get(x)==get(f)?f:x);
		}
		rotate(x);
	}
	root = x;
}
void insert (long long x){
	if (!root){
		t[++tot].cnt++;
		t[tot].val=x;
		root=tot;
		maintain(tot);
		return ;
	}
	long long cur=root,j=0;
	while (1){
		if (t[cur].val==x){
			t[cur].cnt++;
			maintain(cur);
			maintain (j);
			splay(cur);
			break ;
		}
		j=cur;
		cur=t[j].ch[t[j].val<x];
		if (!cur){
			t[++tot].fa=j;
			t[j].ch[x>t[j].val]=tot;
			t[tot].cnt++;
			t[tot].val=x;
			maintain(tot);
			maintain(j);
			splay(tot);
			break;
		}
	}
}
long long rnk (long long x){//查询x的排名
	long long cur=root,res=0;
	while (1){
		if (x<t[cur].val){
			cur=t[cur].ch[0];
		}
		else {
			res+=t[t[cur].ch[0]].size;
			if (t[cur].val==x){
				splay(cur);
				return res+1;
			}
			res+=t[cur].cnt;
			cur=t[cur].ch[1];
		}
	}
}
long long kth (long long x){//查找排名为x的数
	long long cur=root;
	while (1){
		if (t[cur].ch[0]&&x<=t[t[cur].ch[0]].size){
			cur=t[cur].ch[0];
		}
		else {
			x-=t[t[cur].ch[0]].size+t[cur].cnt;
			if (x<=0){
				splay (cur);
				return t[cur].val;
			}
			cur=t[cur].ch[1];
		}
	}
}
long long pre (){//查根节点的前驱
	long long cur=t[root].ch[0];
	if (!cur)return cur;
	while (t[cur].ch[1]){
		cur=t[cur].ch[1];
	}
	splay(cur);
	return cur;
}
long long nxt (){
	long long cur=t[root].ch[1];
	if (!cur)return cur;
	while (t[cur].ch[0]){
		cur=t[cur].ch[0];
	}
	splay(cur);
	return cur;
}
long long cz (long long p){
	long long sum1,sum2;
	long long cur=t[root].ch[0];
	while (t[cur].ch[1]){
		cur=t[cur].ch[1];
	}
	sum1=abss(t[cur].val-p);
	long long cur2=t[root].ch[1];
	while (t[cur2].ch[0]){
		cur=t[cur2].ch[0];
	}
	sum2=abss(t[cur2].val-p);
	return sum1>sum2?cur2:cur;
}
void del (long long x){
	rnk(x);
	if (t[root].cnt>1){
		t[root].cnt--;
		maintain (root);
		return ;
	}
	if (!t[root].ch[0]&&!t[root].ch[1]){
		clear(root);
		root=0;
		return ;
	}
	if (!t[root].ch[0]){
		int cur=root;
		root=t[root].ch[1];
		t[root].fa=0;
		clear(cur);
		return ;
	}
	if (!t[root].ch[1]){
		int cur=root;
		root=t[root].ch[0];
		t[root].fa=0;
		clear(cur);
		return ;
	}
	long long cur=root;
	long long kkkk=pre();
	t[t[cur].ch[1]].fa=root;
	t[root].ch[1]=t[cur].ch[1];
	clear(cur);
	maintain(root);
}
int main (){
	int n,k,x;
	cin>>n;
	insert(2147483647);
	insert(-2147483647);
	for (long long i=1;i<=n;i++){
		scanf ("%d %d",&k,&x);
		if (num==0){
			insert(x);
		}
		else if (num>0){//宠物树
			if (k==0){
				insert(x);
			}
			else {
				insert(x);
				long long cur=cz(x);
				ans=(ans+abss(x-t[cur].val))%mod;
				del(x);
				del(t[cur].val);
			}
		}
		else {
			if (k==1){
				insert(x);
			}
			else {
				insert(x);
				long long cur=cz(x);
				ans=(ans+abss(x-t[cur].val))%mod;
				del(x);
				del(t[cur].val);
			}
		}
		num+=k==0?1:-1;
	}
	cout<<ans;
	return 0;
}
2023/9/20 19:41
加载中...