先diss一波洛谷P3835 这道题数据巨弱 写了一个假的可持久化treap 居然过了 导致之后真正的可持久化treap疯狂wa
最后选择放弃这道题 换了LOJ的一道模板题
普通的无旋treap还是比较简单的
BZOJ3224
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
struct node
{
int ls,rs,value,rand,siz;
}tree[maxn];
int seed=233,root,siz;
int Rand()
{
return seed=seed*48271%2147483647;
}
void reset(int now)
{
tree[now].siz=tree[tree[now].ls].siz+tree[tree[now].rs].siz+1;
}
int merge(int a,int b)
{
if(!a||!b) return a|b;
if(tree[a].rand<tree[b].rand)
{
tree[a].rs=merge(tree[a].rs,b);
reset(a);
return a;
}
else
{
tree[b].ls=merge(a,tree[b].ls),reset(b);
return b;
}
}
pair<int,int> split(int now,int num)
{
if(!now) return make_pair(0,0);
int ls=tree[now].ls;
int rs=tree[now].rs;
if(num==tree[ls].siz)
{
tree[now].ls=0,reset(now);
return make_pair(ls,now);
}
if(num==tree[ls].siz+1)
{
tree[now].rs=0,reset(now);
return make_pair(now,rs);
}
if(num<tree[ls].siz)
{
pair<int,int> T=split(ls,num);
tree[now].ls=T.second,reset(now);
return make_pair(T.first,now);
}
else
{
pair<int,int> T=split(rs,num-tree[ls].siz-1);
tree[now].rs=T.first,reset(now);
return make_pair(now,T.second);
}
}
int getrank(int now,int num)
{
int ret=0,t=1e9;
while(now)
{
if(num<=tree[now].value)
{
if(num==tree[now].value)
t=min(t,ret+tree[tree[now].ls].siz+1);
now=tree[now].ls;
}
else ret+=tree[tree[now].ls].siz+1,now=tree[now].rs;
}
return t==1e9?ret:t;
}
int getnum(int now,int num)
{
while(1)
{
if(tree[tree[now].ls].siz==num-1)
return tree[now].value;
if(tree[tree[now].ls].siz>num-1)
now=tree[now].ls;
else num-=tree[tree[now].ls].siz+1,now=tree[now].rs;
}
}
int lower(int now,int num)
{
int ret;
while(now)
{
if(tree[now].value<num)
ret=tree[now].value,now=tree[now].rs;
else now=tree[now].ls;
}
return ret;
}
int upper(int now,int num)
{
int ret;
while(now)
{
if(tree[now].value>num)
ret=tree[now].value,now=tree[now].ls;
else now=tree[now].rs;
}
return ret;
}
void insert(int num)
{
int r=getrank(root,num);
int now;
pair<int,int> t=split(root,r);
now=++siz;
tree[now].value=num,tree[now].rand=Rand(),tree[now].siz=1;
root=merge(t.first,siz);
root=merge(root,t.second);
}
void del(int num)
{
int r=getrank(root,num);
pair<int,int> t1=split(root,r),t2=split(t1.first,r-1);
root=merge(t2.first,t1.second);
}
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
int op,x;
scanf("%d%d",&op,&x);
switch(op)
{
case 1:insert(x);break;
case 2:del(x);break;
case 3:printf("%d\n",getrank(root,x));break;
case 4:printf("%d\n",getnum(root,x));break;
case 5:printf("%d\n",lower(root,x));break;
case 6:printf("%d\n",upper(root,x));break;
}
}
}