数据结构&图论:欧拉游览树

ETT可以称为欧拉游览树,它是一种和欧拉序有关的动态树(LCT是解决动态树问题的一种方案,这是另一种)

dfs序和欧拉序是把树问题转化到区间问题上然后再用数据结构去维护的利器

通过借助这两种形式能够完成子树的查询和修改,这是LCT所不能胜任的工作

所谓的ETT就是通过动态维护欧拉序来实现动态树

它能完成换父亲(Cut和Link操作)

修改子树(LCT实现不了)

查询结点到根的信息

当然它对比于LCT还是有局限性的

这些操作通过DFS序+Splay也可以完成

只不过我们通俗地把欧拉序+Splay称作ETT而已

这个代码在我交上去的时候WA了一发,printf函数在处理long long的时候一定要小心

代码细节等以后对DFS序和欧拉序了解更加充分以及对数据结构掌握的更好的时候再回过头来看

  1 #include<cstdio>
  2 using namespace std;
  3 const int maxn=200005;
  4 const int maxm=200005;
  5 int n,cnt,tot,m;
  6 int a[maxn],g[maxn];
  7 int lch[maxn],rch[maxn],dfn[maxn];
  8 int fa[maxn],size[maxn],mark[maxn];
  9 long long lazy[maxn],sum[maxn],val[maxn];
 10 int ch[maxn][2];
 11 struct Edge
 12 {
 13     int t,next;
 14 }e[maxm];
 15 inline int read()
 16 {
 17     int x=0,f=1;char ch=getchar();
 18     while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
 19     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 20     return x*f;
 21 }
 22 void addedge(int u,int v)
 23 {
 24     cnt++;
 25     e[cnt].t=v;e[cnt].next=g[u];
 26     g[u]=cnt;
 27 }
 28 void dfs(int x)  //计算欧拉序 
 29 {
 30     lch[x]=++tot;
 31     dfn[lch[x]]=x;
 32     for(int tmp=g[x];tmp;tmp=e[tmp].next)
 33         dfs(e[tmp].t);
 34     rch[x]=++tot;
 35     dfn[rch[x]]=-x;
 36 }
 37 void push_down(int x)
 38 {
 39     if(x&&fa[x]) push_down(fa[x]);
 40     if(x==0||lazy[x]==0) return;
 41     lazy[ch[x][0]]+=lazy[x];
 42     lazy[ch[x][1]]+=lazy[x];
 43     val[ch[x][0]]+=lazy[x]*mark[ch[x][0]];
 44     val[ch[x][1]]+=lazy[x]*mark[ch[x][1]];
 45     sum[ch[x][0]]+=(long long)size[ch[x][0]]*lazy[x];
 46     sum[ch[x][1]]+=(long long)size[ch[x][1]]*lazy[x];
 47     lazy[x]=0;
 48 }
 49 int dir(int x)
 50 {
 51     return ch[fa[x]][1]==x;
 52 }
 53 void push_up(int x)
 54 {
 55     sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+val[x];
 56     size[x]=size[ch[x][0]]+size[ch[x][1]]+mark[x];
 57 }
 58 void rotate(int x,int d)
 59 {
 60     int tmp=ch[x][d^1];
 61     ch[x][d^1]=ch[tmp][d];
 62     if(ch[x][d^1]) fa[ch[x][d^1]]=x;
 63     fa[tmp]=fa[x];
 64     if(fa[x]) ch[fa[x]][dir(x)]=tmp;
 65     fa[x]=tmp;
 66     ch[tmp][d]=x;
 67     push_up(x);push_up(tmp);
 68 }
 69 void splay(int x,int goal)
 70 {
 71     push_down(x);
 72     while(fa[x]!=goal)
 73     {
 74         if(fa[fa[x]]!=goal&&dir(x)==dir(fa[x]))
 75             rotate(fa[fa[x]],dir(x)^1);
 76         rotate(fa[x],dir(x)^1);
 77     }
 78 }
 79 int find_left(int x)
 80 {
 81     splay(x,0);
 82     x=ch[x][0];
 83     while(ch[x][1]) x=ch[x][1];
 84     return x;
 85 }
 86 int find_right(int x)
 87 {
 88     splay(x,0);
 89     x=ch[x][1];
 90     while(ch[x][0]) x=ch[x][0];
 91     return x;
 92 }
 93 int build(int l,int r)
 94 {
 95     if(l>r) return 0;
 96     int mid=(l+r)>>1;
 97     if(mid<r)
 98     {
 99         ch[mid][1]=build(mid+1,r);
100         fa[ch[mid][1]]=mid;
101     }
102     if(l<mid)
103     {
104         ch[mid][0]=build(l,mid-1);
105         fa[ch[mid][0]]=mid;
106     }
107     if(dfn[mid]>0) val[mid]=a[dfn[mid]];
108     else val[mid]=-a[-dfn[mid]];
109     
110     if(dfn[mid]>0) mark[mid]=1;
111     else mark[mid]=-1;
112     
113     push_up(mid);
114     return mid;
115 }
116 int main()
117 {
118     int x,y; 
119     char opt;
120     n=read();
121     for(int i=2;i<=n;i++)
122     {
123         x=read();
124         addedge(x,i);
125     }
126     dfs(1);
127     for(int i=1;i<=n;i++) a[i]=read();
128     build(1,tot+1);
129     m=read();
130     while(m--)
131     {
132         opt=getchar();
133         while(opt!='Q'&&opt!='C'&&opt!='F') opt=getchar();
134         x=read();
135         if(opt=='Q')
136         {
137             splay(lch[x],0);
138             printf("%lld\n",sum[ch[lch[x]][0]]+val[lch[x]]);
139         }
140         else if(opt=='C')
141         {
142             y=read();
143             int aa=find_left(lch[x]),bb=find_right(rch[x]);
144             splay(aa,0);splay(bb,aa);
145             int tmp=ch[bb][0];
146             ch[bb][0]=0;
147             push_up(bb);push_up(aa);
148             x=find_left(rch[y]);
149             splay(x,0);splay(rch[y],x);
150             fa[tmp]=rch[y];
151             ch[rch[y]][0]=tmp;
152             push_up(rch[y]);push_up(x);
153         }
154         else
155         {
156             y=read();
157             int aa=find_left(lch[x]),bb=find_right(rch[x]);
158             splay(aa,0);splay(bb,aa);
159             lazy[ch[bb][0]]+=y;
160             val[ch[bb][0]]+=y*mark[ch[bb][0]];
161             sum[ch[bb][0]]+=(long long)size[ch[bb][0]]*y;
162         }
163     }
164     return 0;
165 }

 

    原文作者:静听风吟。
    原文地址: https://www.cnblogs.com/aininot260/p/9517665.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞