题意:一开始给定n个盒子的摆的嵌套关系。有两种操作,1.MOVE x y:把编号x的箱子及其包含的箱子放进编号为y的箱子;
2.QUERY x :查询编号x的箱子所在的最靠外的箱子。
方法一:splay+括号序
思路:将全部的树逐个dfs,这样对于每一棵树都可以得到一个括号序列,对于MOVE操作,我们将那个根所在的左右括号的一整段
取出,连接到新的结点的左括号右边,这么做我们可以保证得到的一定也是一个括号序列。我们将x和x+n分别旋根,这样我们可以得到一个x和x+n,x+n是根,x是其左子树的某一个结点,这样x的左子树和x+n的右子树是无效的,我们剪掉它们,并且将x+n的右子树接到x的左子树最后,接着把x+n旋根,保证平衡性。对于QUERY操作,我们直接去找其结点所在的括号序列靠最左边的是谁就可以了。详见代码:
/*********************************************************
file name: hdu2475.cpp
author : kereo
create time: 2015年02月18日 星期三 14时29分43秒
*********************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
const int sigma_size=26;
const int N=100+50;
const int MAXN=100000+50;
const int inf=0x3fffffff;
const double eps=1e-8;
const int mod=1000000000+7;
#define L(x) (x->ch[0])
#define R(x) (x->ch[1])
#define PII pair<int, int>
#define mk(x,y) make_pair((x),(y))
int n,m,edge_cnt,cnt;
char str[N];
int head[MAXN],seq[MAXN],vis[MAXN];
struct Edge{
int v,next;
}edge[MAXN];
struct node{
node *fa,*ch[2];
}nod[MAXN],*root,*null;
struct Splay{
void rotate(node *x,int d){
node *y=x->fa;
//push_down(y); push_down(x);
y->ch[d^1]=x->ch[d];
if(x->ch[d]!=null)
x->ch[d]->fa=y;
x->fa=y->fa;
if(y->fa!=null){
int d=y->fa->ch[0] == y ? 0 : 1;
y->fa->ch[d]=x;
}
y->fa=x; x->ch[d]=y;
//push_up(y);
}
void splay(node *x,n