Splay TLE on #10 求助
查看原帖
Splay TLE on #10 求助
640499
WCPWCPWCP楼主2022/8/25 19:06
#include<iostream>
#include<climits>
#define maxn 2000010
using namespace std;

struct node{
	int s[2],p,cnt,v,siz;
	void init(int p1,int v1){
		p=p1,v=v1;
		cnt=siz=1;
	}
}tr[maxn];
int root,idex,ans=0,last=0;
int read(){
	int res=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-'){
			f=f*-1;
		}
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		res=res*10+c-'0';
		c=getchar();
	}
	return res*f;
}
void write(int x) {
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
void pushup(int node){
	tr[node].siz=tr[tr[node].s[0]].siz+tr[tr[node].s[1]].siz+tr[node].cnt;
}
void rotate(int x){
	int y=tr[x].p,z=tr[y].p;
	int k=tr[y].s[1]==x;
	tr[y].s[k]=tr[x].s[k^1];
	tr[tr[x].s[k^1]].p=y;
	tr[x].s[k^1]=y;
	tr[y].p=x;
	tr[x].p=z;
	tr[z].s[tr[z].s[1]==y]=x;
	pushup(y);
	pushup(x);
}
void splay(int x,int u){
	while(tr[x].p!=u){
		int y=tr[x].p,z=tr[y].p;
		if(z!=u){
			if((tr[z].s[0]==y)^(tr[y].s[0]==x)){
				rotate(x);
			}
			else{
				rotate(y);
			}
		}
		else{
			rotate(x);
		}
	}
	if(u==0) root=x;
}
void find(int v){
	int x=root;
	while(tr[x].s[v>tr[x].v]&&v!=tr[x].v){   //  ???
		x=tr[x].s[v>tr[x].v];
	}
	splay(x,0);
}
int find_xrk(int x){   // 需要保证查找的数在树里面 ,也可以先加入一个数再删除掉 
	find(x);
	return tr[tr[root].s[0]].siz; 
}
inline int getrank(int x){  // 不需要保证数在树里面 
    int cur=root,ret=0;
    while(cur){
        if(tr[cur].v==x){
            ret+=tr[tr[cur].s[0]].siz;
            splay(cur,0); return ret;
        } 
		if(tr[cur].v>x)
        cur=tr[cur].s[0];
        else
        ret+=tr[tr[cur].s[0]].siz+tr[cur].cnt,cur=tr[cur].s[1];
    } 
    if(tr[cur].v==x){
    	splay(cur,0);
	}
	else{
		splay(tr[cur].p,0);
	}
	return ret;
}
int find_rkx(int k){
	int x=root;
	while(1){
		if(tr[x].cnt+tr[tr[x].s[0]].siz<k){
			k-=tr[x].cnt+tr[tr[x].s[0]].siz;
			x=tr[x].s[1];
		}
		else{
			if(tr[tr[x].s[0]].siz>=k){
				x=tr[x].s[0];
			}
			else{
				break;
			}
		}
	}
	splay(x,0);
	return tr[x].v;
}
int find_pre(int v){
	find(v);
	int x=root;
	if(tr[x].v<v){
		return x;
	}
	x=tr[x].s[0];
	while(tr[x].s[1]){
		x=tr[x].s[1];
	}
	//splay(x,0);
	return x;
}
int find_rea(int v){
	find(v);
	int x=root;
	if(tr[x].v>v){
		return x;
	}
	x=tr[x].s[1];
	while(tr[x].s[0]){
		x=tr[x].s[0];
	}
	//splay(x,0);
	return x;
}
void ldelete(int x){
	int pre=find_pre(x);
	int rea=find_rea(x);
	splay(pre,0);
	splay(rea,pre);
	if(tr[tr[rea].s[0]].cnt>1){
		tr[tr[rea].s[0]].cnt--;
		splay(tr[rea].s[0],0);
	}
	else{
		tr[rea].s[0]=0;
		splay(rea,0);
	}
}
void insert(int v){
	int x=root,p=0;
	while(x&&tr[x].v!=v){
		p=x;x=tr[x].s[v>tr[x].v];
	}
	if(x) tr[x].cnt++;
	else{
		x=++idex;
		tr[p].s[v>tr[p].v]=x;
		tr[x].init(p,v);
	}
	splay(x,0);
}

int main()
{
	int n,m;
	n=read(),m=read();
	insert(-INT_MAX);
	insert(INT_MAX);
	for(int i=1;i<=n;i++){
		int a;
		a=read();
		insert(a);
	}
	for(int i=1;i<=m;i++){
		int op,x;
		op=read(),x=read();	
		x=(x^last);
		if(op==1){
			insert(x);
		}
		else if(op==2){
			ldelete(x);
		}
		else if(op==3){
			int tmp=getrank(x);
			ans^=tmp;
			last=tmp;
		}
		else if(op==4){
			int tmp=find_rkx(x+1);
			ans^=tmp;
			last=tmp;
		}
		else if(op==5){
			int tmp=tr[find_pre(x)].v;
			ans^=tmp;
			last=tmp;
		}
		else if(op==6){
			int tmp=tr[find_rea(x)].v;
			ans^=tmp;
			last=tmp;
		}
	}
	write(ans);
	return 0;
}
2022/8/25 19:06
加载中...