您的位置:首页 > 其它

HDU 2475 Box(splay)

2013-03-28 21:32 429 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2475

题意:给出一棵树,两种操作:(1)修改某棵子树的父节点;(2)查询某个节点的根节点。

思路:每个题目中的箱子看做两个箱子i和i+n,(i,i+n)之间的为在i箱子中的。对于第一种操作,比如将u的父节点改为v,首先将u转到根节点,然后将u+n根节点右孩子,然后u子树就可以被整体切下。然后将另外两部分连接在一起。然后将v转到根,将v之后最左的节点转到v右孩子,然后将u插入v右孩子的左孩子。查询直接将u转到根,找到最左孩子。

struct node
{
int id;
node *c[2],*f;
};

node a
,*nullNode;
int n,m;

void rotate(node *x,int k)
{
node *y=x->f;
y->c[k]=x->c[!k];
y->c[k]->f=y;
x->f=y->f;
if(y->f->c[0]==y) y->f->c[0]=x;
else y->f->c[1]=x;
y->f=x;
x->c[!k]=y;
}

void splay(node *x,node *y)
{
while(x->f!=y)
{
if(x->f->f==y)
{
if(x->f->c[0]==x) rotate(x,0);
else rotate(x,1);
}
else if(x->f->f->c[0]==x->f)
{
if(x->f->c[0]==x) rotate(x->f,0);
else rotate(x,1);
rotate(x,0);
}
else
{
if(x->f->c[1]==x) rotate(x->f,1);
else rotate(x,0);
rotate(x,1);
}
}
}

void change(int u,int v)
{
if(u==v) return;
splay(a+u,nullNode);
splay(a+u+n,a+u);
node *p;
if(v!=0)
{
p=a+v;
while(p!=nullNode)
{
if(p==a[u+n].c[0]) return;
p=p->f;
}
}
node *x=a[u].c[0],*y=a[u+n].c[1];
a[u].c[0]=nullNode;
a[u+n].c[1]=nullNode;
x->f=y->f=nullNode;
if(x!=nullNode&&y!=nullNode)
{
while(y->c[0]!=nullNode) y=y->c[0];
y->c[0]=x;
x->f=y;
}
if(v==0) return;
splay(a+v,nullNode);
p=a[v].c[1];
while(p->c[0]!=nullNode) p=p->c[0];
splay(p,a+v);
p->c[0]=a+u;
a[u].f=p;
}

int query(int x)
{
splay(a+x,nullNode);
node *p=a+x;
while(p->c[0]!=nullNode) p=p->c[0];
return p->id;
}

int get()
{
int x=0,flag=1;
char c=getchar();
while(!isdigit(c)) c=getchar();
if(c=='-')
{
flag=-1,c=getchar();
while(!isdigit(c)) c=getchar();
}
while(isdigit(c))
{
x=x*10+c-'0';
c=getchar();
}
return x*flag;
}

vector<int> g
;
int isRoot
;

node *build(int u)
{
node *pre=a+u,*last=a+u,*cur;
int i,v;
FOR0(i,SZ(g[u]))
{
v=g[u][i];
last=build(v);
pre->c[1]=a+v;
a[v].f=pre;
pre=last;
}
cur=a+u+n;
last->c[1]=cur;
cur->f=last;
return a+u+n;
}

void init()
{
nullNode=new node();
nullNode->c[0]=nullNode->c[1]=nullNode->f=nullNode;
int i,u;
FOR1(i,n) g[i].clear();
clr(isRoot,0);
FOR1(i,(n+n))
{
a[i].c[0]=a[i].c[1]=a[i].f=nullNode;
a[i].id=i;
}
FOR1(i,n)
{
u=get();
if(u==0) isRoot[i]=1;
else g[u].pb(i);
}
node *p;
FOR1(i,n) if(isRoot[i])
{
build(i);
a[i].f=nullNode;
}
}

int main()
{
bool flag=false;
while(scanf("%d",&n)!=-1)
{
if(flag) puts("");
else flag=true;
init();
int u,v;
m=get();
char op[10];
while(m--)
{
scanf("%s",op);
if(op[0]=='M')
{
u=get(),v=get();
change(u,v);
}
else u=get(),PR(query(u));
}
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: