「模板」 可持久化平衡树

<题目链接>

(There's suddenly something wrong with my Chinese Input Method...)

Persistable FHQ_Treap.

MLE 2 points after debugging for a whole evening for the pointers.

At last I chose to use array.

Although AC, upset.

#include <climits>
#include <cstdio>
#include <cstdlib>
const int MAXN=500010;
int n;
class FHQ_Treap
{
public:
FHQ_Treap(void):cnt(0)
{
rt[0]=0;
}
void Copy(int i,int j)
{
rt[i]=rt[j];
}
void Insert(int i,int x)
{
int l,r,t=NewNode(x);
Split(rt[i],x,l,r);
Merge(l,l,t);
Merge(rt[i],l,r);
}
void Delete(int i,int x)
{
int l,r,t;
Split(rt[i],x,l,r);
Split(l,x-1,l,t);
Merge(t,s[t].c[0],s[t].c[1]);
Merge(l,l,t);
Merge(rt[i],l,r);
}
void Rank(int i,int x)
{
int l,r;
Split(rt[i],x-1,l,r);
printf("%d\n",s[l].size+1);
Merge(rt[i],l,r);
}
void Find(int i,int x)
{
printf("%d\n",FindKth(rt[i],x));
}
void Prev(int i,int x)
{
int l,r;
Split(rt[i],x-1,l,r);
printf("%d\n",FindKth(l,s[l].size));
Merge(rt[i],l,r);
}
void Next(int i,int x)
{
int l,r;
Split(rt[i],x,l,r);
printf("%d\n",FindKth(r,1));
Merge(rt[i],l,r);
}
private:
int cnt,rt[MAXN];
struct Node
{
int v,p,size,c[2];
Node(int v=0,int p=0,int size=0):v(v),p(p),size(size)
{
c[0]=c[1]=0;
}
}s[MAXN*50];
void Update(int i)
{
s[i].size=s[s[i].c[0]].size+s[s[i].c[1]].size+1;
}
int NewNode(int x)
{
s[++cnt]=Node(x,rand(),1);
return cnt;
}
void Split(int i,int x,int &l,int &r)
{
if(!i)
{
l=r=0;
return;
}
if(x<s[i].v)
{
r=++cnt;
s[r]=s[i];
Split(s[r].c[0],x,l,s[r].c[0]);
Update(r);
}
else
{
l=++cnt;
s[l]=s[i];
Split(s[l].c[1],x,s[l].c[1],r);
Update(l);
}
}
void Merge(int &i,int l,int r)
{
if(!l || !r)
{
i=l|r;
return;
}
i=++cnt;
if(s[l].p>s[r].p)
{
i=r;
Merge(s[r].c[0],l,s[r].c[0]);
}
else
{
i=l;
Merge(s[l].c[1],s[l].c[1],r);
}
Update(i);
}
int FindKth(int i,int x)
{
int t;
while(x^(t=s[s[i].c[0]].size+1))
if(x>t)
x-=t,i=s[i].c[1];
else
i=s[i].c[0];
return s[i].v;
}
}*T=new FHQ_Treap;
int main(int argc,char** argv)
{
scanf("%d",&n);
for(int i=1,j,opt,x;i<=n;++i)
{
scanf("%d %d %d",&j,&opt,&x);
T->Copy(i,j);
switch(opt)
{
case 1:
T->Insert(i,x);
break;
case 2:
T->Delete(i,x);
break;
case 3:
T->Rank(i,x);
break;
case 4:
T->Find(i,x);
break;
case 5:
T->Prev(i,x);
break;
case 6:
T->Next(i,x);
break;
}
}
delete T;
return 0;
}