萌新求调 treap ,20pts 求助
查看原帖
萌新求调 treap ,20pts 求助
376997
Harry27182SDream楼主2021/11/14 09:47

rt,一直 20pts ,好像有输出负数和奇怪的数,求调

#include<bits/stdc++.h>
#define int long long
#define inf 0x3f3f3f3f
using namespace std;
int size[1100005],val[1100005],num[11000005],rd[1100005],son[1100005][2];
int n,cnt,root,op,x,m,last,ans;
void pushup(int p)
{
	size[p]=size[son[p][0]]+size[son[p][1]]+num[p];
} 
void rotate(int &p,int d)
{
	int k=son[p][d^1];
	son[p][d^1]=son[k][d];
	son[k][d]=p;
	pushup(p);
	pushup(k);
	p=k;
}
void insert(int &p,int x)
{
	if(!p)
	{
		p=++cnt;
		size[p]=num[p]=1;
		val[p]=x;
		rd[p]=rand();
		return;
	}
	if(val[p]==x)
	{
		num[p]++;
		size[p]++;
		return;
	}
	int d=(x>val[p]);
	insert(son[p][d],x);
	if(rd[p]<rd[son[p][d]])rotate(p,d^1);
	pushup(p);
}
void del(int &p,int x)
{
	if(!p)return;
	if(x<val[p])del(son[p][0],x);
	else if(x>val[p])del(son[p][1],x);
	else
	{
		if(!son[p][0]&&!son[p][1])
		{
			num[p]--;size[p]--;
			if(!num[p])p=0;
		}
		else if(!son[p][1])
		{
			rotate(p,1);
			del(son[p][1],x);
		}
		else if(!son[p][0])
		{
			rotate(p,0);
			del(son[p][0],x);
		}
		else
		{
			int d=(rd[son[p][0]]>rd[son[p][1]]);
			rotate(p,d);
			del(son[p][d],x);
		}
	}
	pushup(p);
}
int rnk(int p,int x)
{
	if(!p)return 1;
	if(val[p]==x)return size[son[p][0]]+1;
	if(val[p]<x)return size[son[p][0]]+num[p]+rnk(son[p][1],x);
	if(val[p]>x)return rnk(son[p][0],x);
}
int find(int p,int x)
{
	if(!p)return 0;
	if(size[son[p][0]]>=x)return find(son[p][0],x);
	else if(size[son[p][0]]+num[p]<x)return find(son[p][1],x-num[p]-size[son[p][0]]);
	else return val[p];
}
int pre(int p,int x)
{
	if(!p)return -inf;
	if(val[p]>=x)return pre(son[p][0],x);
	else return max(val[p],pre(son[p][1],x));
}
int suc(int p,int x)
{
	if(!p)return inf;
	if(val[p]<=x)return suc(son[p][1],x);
	else return min(val[p],suc(son[p][0],x));
}
signed main()
{
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++)scanf("%lld",&x),insert(root,x);
    while(m--)
    {
        scanf("%lld%lld",&op,&x);
        x^=last;
        if(op==1)insert(root,x);
        else if(op==2)del(root,x);
        else if(op==3)last=rnk(root,x),ans^=last;
        else if(op==4)last=find(root,x),ans^=last;
        else if(op==5)last=pre(root,x),ans^=last;
        else last=suc(root,x),ans^=last;
    }
    printf("%lld",ans);
    return 0;
}
2021/11/14 09:47
加载中...