# bzoj3786 星系探索（ETT）

ETT就是Euler Tour Tree，用平衡树来维护欧拉序。

1.The first way is to write down all edges of the tree, directed, in order of DFS. This is how ETT is defined on
2.The second way is to store vertices. Each vertex is added to the array twice: when we descend into it and when we leave it.
3.The third way implies storing vertices too, but now each vertex is added every time when we visit it (when descending from parent and when returning from child)

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 100010
inline char gc(){
static char buf[1<<16],*S,*T;
return *S++;
}
int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=gc();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
return x*f;
}
inline char get_S(){
char ch=gc();
while(ch<'A'||ch>'Z') ch=gc();return ch;
}
int n,fa[N<<1],c[N<<1][2],sz[N<<1],in[N],out[N],dfn=0,w[N],sig[N<<1],rt=0,q[N<<1];
ll v[N<<1],sum[N<<1],tag[N<<1];
vector<int>Son[N];
void dfs(int x){
in[x]=++dfn;v[dfn]=w[x];sig[dfn]=1;
for(int i=0;i<Son[x].size();++i) dfs(Son[x][i]);
out[x]=++dfn;v[dfn]=-w[x];sig[dfn]=-1;
}
inline void update(int p){
int l=c[p][0],r=c[p][1];
sz[p]=sz[l]+sz[r]+sig[p];
sum[p]=sum[l]+sum[r]+v[p];
}
tag[p]+=val;v[p]+=val*sig[p];sum[p]+=(ll)val*sz[p];
}
inline void pushdown(int p){
if(!tag[p]) return;
int l=c[p][0],r=c[p][1];
}
inline void build(int &p,int l,int r){
int mid=l+r>>1;p=mid;tag[p]=0;
if(l<mid) build(c[p][0],l,mid-1),fa[c[p][0]]=p;
if(r>mid) build(c[p][1],mid+1,r),fa[c[p][1]]=p;update(p);
}
inline void rotate(int x,int &k){
int y=fa[x],z=fa[y],l=x==c[y][1],r=l^1;
if(y==k) k=x;
else c[z][y==c[z][1]]=x;
fa[c[x][r]]=y;fa[y]=x;fa[x]=z;
c[y][l]=c[x][r];c[x][r]=y;update(y);update(x);
}
inline void splay(int x,int &k){
int top=0;q[++top]=x;
for(int xx=x;xx!=k;xx=fa[xx]) q[++top]=fa[xx];
while(top) pushdown(q[top--]);
while(x!=k){
int y=fa[x],z=fa[y];
if(y!=k){
if(x==c[y][1]^y==c[z][1]) rotate(x,k);
else rotate(y,k);
}rotate(x,k);
}
}
inline int findpre(int x){
splay(x,rt);int res=c[x][0];
while(c[res][1]) res=c[res][1];
return res;
}
inline int findsucc(int x){
splay(x,rt);int res=c[x][1];
while(c[res][0]) res=c[res][0];
return res;
}
inline int split(int xx,int yy){
int x=findpre(xx),y=findsucc(yy);
splay(x,rt);splay(y,c[rt][1]);return c[y][0];
}
inline int del1(int l,int r){
int x=split(l,r),y=fa[x];
c[y][0]=fa[x]=0;update(y);update(fa[y]);return x;
}inline void add(int l,int r,int val){
int x=split(l,r),y=fa[x];
}
int main(){
//  freopen("a.in","r",stdin);
while(m--){
if(op=='Q'){
splay(in[x],rt);
printf("%lld\n",sum[c[in[x]][0]]+v[in[x]]);continue;
if(op=='C'){
x=del1(in[x],out[x]);
int xx=findpre(out[y]),yy=out[y];
splay(xx,rt);splay(yy,c[rt][1]);c[yy][0]=x;fa[x]=yy;update(yy);update(xx);
}return 0;
}

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120