RT,写的treap,在洛谷上交了七八次都是AC,但在本机测的时候大概两三次就会随机WA一次。 请问是我自己的代码写臭了吗?还是treap特性?
代码如下:
#include<bits/stdc++.h>
#define inf 1000000000
using namespace std;
struct T{
int val,cnt,rnd,l,r,sz;
}t[100011];
int n,tot,ans,root;
int New(int x)
{
t[++tot].val=x;
t[tot].cnt=t[tot].sz=1,t[tot].rnd=rand();
return tot;
}
void upd(int x)
{
t[x].sz=t[t[x].l].sz+t[t[x].r].sz+t[x].cnt;
}
void bui()
{
New(-inf);New(inf);
root=1,t[1].r=2;
upd(root);
}
void zig(int &x)
{
int y=t[x].l;
t[x].l=t[y].r,t[y].r=x,x=y;
upd(t[x].r);upd(x);
}
void zag(int &x)
{
int y=t[x].r;
t[x].r=t[y].l,t[y].l=x,x=y;
upd(t[x].l);upd(x);
}
void ins(int &x,int z)
{
if(!x) {x=New(z);return;}
if(t[x].val==z)
{
t[x].cnt++;upd(x);
return;
}
if(z<t[x].val)
{
ins(t[x].l,z);
if(t[x].rnd<t[t[x].l].rnd) zig(x);
}
else
{
ins(t[x].r,z);
if(t[x].rnd>t[t[x].r].rnd) zag(x);
}
upd(x);
}
void del(int &x,int z)
{
if(!x) return;
if(z==t[x].val)
{
if(t[x].cnt>1)
{
t[x].cnt--;upd(x);
return;
}
if(t[x].l||t[x].r)
{
t[t[x].l].rnd>t[t[x].r].rnd?zig(x),del(t[x].r,z):zag(x),del(t[x].l,z);
upd(x);
}
else x=0;
return;
}
z<t[x].val?del(t[x].l,z):del(t[x].r,z);
upd(x);
}
int getrank(int x,int z)
{
if(!x) return 0;
if(z==t[x].val) return t[t[x].l].sz+1;
if(z<=t[x].val) return getrank(t[x].l,z);
return getrank(t[x].r,z)+t[t[x].l].sz+t[x].cnt;
}
int getval(int x,int z)
{
if(!x) return inf;
if(t[t[x].l].sz>=z) return getval(t[x].l,z);
if(t[t[x].l].sz+t[x].cnt>=z) return t[x].val;
return getval(t[x].r,z-t[t[x].l].sz-t[x].cnt);
}
int getlas(int z)
{
int s=1,x=root;
while(x)
{
if(z==t[x].val)
{
if(t[x].l)
{
x=t[x].l;
while(t[x].r) x=t[x].r;
s=x;break;
}
}
if(t[x].val<z&&t[x].val>t[s].val) s=x;
x=z<t[x].val?t[x].l:t[x].r;
}
return t[s].val;
}
int getnxt(int z)
{
int s=2,x=root;
while(x)
{
if(z==t[x].val)
{
if(t[x].r)
{
x=t[x].r;
while(t[x].l) x=t[x].l;
s=x;
}
break;
}
if(t[x].val>z&&t[x].val<t[s].val) s=x;
x=z<t[x].val?t[x].l:t[x].r;
}
return t[s].val;
}
int main()
{
// freopen("P3369.in","r",stdin);
// freopen("P3369.out","w",stdout);
srand(time(0));
scanf("%d",&n);
bui();
int op,x;
while(n--)
{
scanf("%d%d",&op,&x);
switch(op)
{
case 1:{
ins(root,x);
break;
}
case 2:{
del(root,x);
break;
}
case 3:{
ans=getrank(root,x)-1;
printf("%d\n",ans);
break;
}
case 4:{
ans=getval(root,x+1);
printf("%d\n",ans);
break;
}
case 5:{
ans=getlas(x);
printf("%d\n",ans);
break;
}
case 6:{
ans=getnxt(x);
printf("%d\n",ans);
break;
}
}
}
return 0;
}