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

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

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

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

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

修改子树(LCT实现不了)

查询结点到根的信息

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

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

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

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

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

 #include<cstdio>
using namespace std;
const int maxn=;
const int maxm=;
int n,cnt,tot,m;
int a[maxn],g[maxn];
int lch[maxn],rch[maxn],dfn[maxn];
int fa[maxn],size[maxn],mark[maxn];
long long lazy[maxn],sum[maxn],val[maxn];
int ch[maxn][];
struct Edge
{
int t,next;
}e[maxm];
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>'') {if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void addedge(int u,int v)
{
cnt++;
e[cnt].t=v;e[cnt].next=g[u];
g[u]=cnt;
}
void dfs(int x) //计算欧拉序
{
lch[x]=++tot;
dfn[lch[x]]=x;
for(int tmp=g[x];tmp;tmp=e[tmp].next)
dfs(e[tmp].t);
rch[x]=++tot;
dfn[rch[x]]=-x;
}
void push_down(int x)
{
if(x&&fa[x]) push_down(fa[x]);
if(x==||lazy[x]==) return;
lazy[ch[x][]]+=lazy[x];
lazy[ch[x][]]+=lazy[x];
val[ch[x][]]+=lazy[x]*mark[ch[x][]];
val[ch[x][]]+=lazy[x]*mark[ch[x][]];
sum[ch[x][]]+=(long long)size[ch[x][]]*lazy[x];
sum[ch[x][]]+=(long long)size[ch[x][]]*lazy[x];
lazy[x]=;
}
int dir(int x)
{
return ch[fa[x]][]==x;
}
void push_up(int x)
{
sum[x]=sum[ch[x][]]+sum[ch[x][]]+val[x];
size[x]=size[ch[x][]]+size[ch[x][]]+mark[x];
}
void rotate(int x,int d)
{
int tmp=ch[x][d^];
ch[x][d^]=ch[tmp][d];
if(ch[x][d^]) fa[ch[x][d^]]=x;
fa[tmp]=fa[x];
if(fa[x]) ch[fa[x]][dir(x)]=tmp;
fa[x]=tmp;
ch[tmp][d]=x;
push_up(x);push_up(tmp);
}
void splay(int x,int goal)
{
push_down(x);
while(fa[x]!=goal)
{
if(fa[fa[x]]!=goal&&dir(x)==dir(fa[x]))
rotate(fa[fa[x]],dir(x)^);
rotate(fa[x],dir(x)^);
}
}
int find_left(int x)
{
splay(x,);
x=ch[x][];
while(ch[x][]) x=ch[x][];
return x;
}
int find_right(int x)
{
splay(x,);
x=ch[x][];
while(ch[x][]) x=ch[x][];
return x;
}
int build(int l,int r)
{
if(l>r) return ;
int mid=(l+r)>>;
if(mid<r)
{
ch[mid][]=build(mid+,r);
fa[ch[mid][]]=mid;
}
if(l<mid)
{
ch[mid][]=build(l,mid-);
fa[ch[mid][]]=mid;
}
if(dfn[mid]>) val[mid]=a[dfn[mid]];
else val[mid]=-a[-dfn[mid]]; if(dfn[mid]>) mark[mid]=;
else mark[mid]=-; push_up(mid);
return mid;
}
int main()
{
int x,y;
char opt;
n=read();
for(int i=;i<=n;i++)
{
x=read();
addedge(x,i);
}
dfs();
for(int i=;i<=n;i++) a[i]=read();
build(,tot+);
m=read();
while(m--)
{
opt=getchar();
while(opt!='Q'&&opt!='C'&&opt!='F') opt=getchar();
x=read();
if(opt=='Q')
{
splay(lch[x],);
printf("%lld\n",sum[ch[lch[x]][]]+val[lch[x]]);
}
else if(opt=='C')
{
y=read();
int aa=find_left(lch[x]),bb=find_right(rch[x]);
splay(aa,);splay(bb,aa);
int tmp=ch[bb][];
ch[bb][]=;
push_up(bb);push_up(aa);
x=find_left(rch[y]);
splay(x,);splay(rch[y],x);
fa[tmp]=rch[y];
ch[rch[y]][]=tmp;
push_up(rch[y]);push_up(x);
}
else
{
y=read();
int aa=find_left(lch[x]),bb=find_right(rch[x]);
splay(aa,);splay(bb,aa);
lazy[ch[bb][]]+=y;
val[ch[bb][]]+=y*mark[ch[bb][]];
sum[ch[bb][]]+=(long long)size[ch[bb][]]*y;
}
}
return ;
}

数据结构&图论:欧拉游览树的更多相关文章

  1. BZOJ 3786: 星系探索 欧拉游览树

    一个叫 Euler-Tour-Tree 的数据结构,说白了就是用 Splay_Tree 维护欧拉序 #include <cstring> #include <algorithm> ...

  2. 三维CAD塑造——基于所述基本数据结构一半欧拉操作模型

    三维CAD塑造--基于所述基本数据结构一半欧拉操作模型(elar, B_REP) (欧拉操作  三维CAD建模课程 三维CAD塑造 高曙明老师  渲染框架 brep 带洞 带柄 B_REP brep ...

  3. HYSBZ - 3813 奇数国 欧拉函数+树状数组(线段树)

    HYSBZ - 3813奇数国 中文题,巨苟题,巨无敌苟!!首先是关于不相冲数,也就是互质数的处理,欧拉函数是可以求出互质数,但是这里的product非常大,最小都2100000,这是不可能实现的.所 ...

  4. POJ2513 欧拉 + 字典树

    POJ 2513 有N根木棒,一根木棒有2头,我们把每头涂色(相同或不同),如果2根木棒有相同颜色的一端就可以连接,颜色全部不同就不能连接,现在给你N根木棒以及它们的颜色,问最后能不能链接成1条链. ...

  5. [BZOJ3772]精神污染 主席树上树+欧拉序

    3772: 精神污染 Time Limit: 10 Sec  Memory Limit: 64 MB Description 兵库县位于日本列岛的中央位置,北临日本海,南面濑户内海直通太平洋,中央部位 ...

  6. BZOJ 4034 树上操作(树的欧拉序列+线段树)

    刷个清新的数据结构题爽一爽? 题意: 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x ...

  7. 树的遍历顺序 - dfs序|欧拉序|dfn序(备忘)

    (仅作备忘) dfs序是dfs过程中对于某节点进入这个节点的子树和离开子树的顺序 满足每个节点都会在dfs序上出现恰好两次 任意子树的dfs序都是连续的 欧拉序是dfs过程中经过节点的顺序 每个节点至 ...

  8. LightOJ 1370 Bi-shoe and Phi-shoe 欧拉函数+线段树

    分析:对于每个数,找到欧拉函数值大于它的,且标号最小的,预处理欧拉函数,然后按值建线段树就可以了 #include <iostream> #include <stdio.h> ...

  9. HDU 4836 The Query on the Tree lca || 欧拉序列 || 动态树

    lca的做法还是非常明显的.简单粗暴, 只是不是正解.假设树是长链就会跪,直接变成O(n).. 最后跑的也挺快,出题人还是挺阳光的.. 动态树的解法也是听别人说能ac的.预计就是放在splay上剖分一 ...

随机推荐

  1. hadoop问题集(1)

        参考: http://dataunion.org/22887.html 1.mapreduce_shuffle does not exist 执行任何时报错: Container launch ...

  2. es6从零学习(五):Module的语法

    es6从零学习(五):Module的语法 ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量 一:es6模块化和 CommonJS 和 AMD 模块 (运行 ...

  3. “Hello World!”团队召开的第十二次会议

    今天是我们团队“Hello World!”团队召开的第十二次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 一.会议时间 2 ...

  4. 20172314 Android程序设计 实验四

    课程:<程序设计与数据结构> 班级: 1723 姓名: 方艺雯 学号:20172314 实验教师:王志强 实验日期:2018年5月30日 必修/选修: 必修 1.实验内容及要求 (1)An ...

  5. tomcat端口号修改

    修改Tomcat的端口号: 在默认情况下,tomcat的端口是8080,如果出现8080端口号冲突,用如下方法可以修改Tomcat的端口号: 首先: 在Tomcat的根(安装)目录下,有一个conf文 ...

  6. javaIO--字符流

    java提供字符流对自否刘式文件进行数据读写操作.字符输入流类是Reader及其子类,输出流是Writer及其子类. 另外,上一篇javaIO写的是字节流,字节流方式也可以对以字符为基本类型的流式文件 ...

  7. javaIO--字节流

    流---是指的一组有序的.有气垫和重点的字节集合,是对的护具传输的总称或者抽象. 流采用缓冲区技术,当写一个数据时,系统将数据发送到缓冲区而不是外部设备(如硬盘),当读一个数据时,系统实际是从缓冲区读 ...

  8. Javascript动态方法调用与参数修改的问题

    Javascript中可以对所传参数在函数内进行修改,如下 ? 1 2 3 4 5 function func1(name) {     name = 'lily';     alert(name); ...

  9. Launch Image消失时添加动画

    CGSize viewSize = self.window.bounds.size; NSString *viewOrientation = @"Portrait"; //横屏请设 ...

  10. QT分析之消息事件机制

    原文地址:http://blog.163.com/net_worm/blog/static/127702419201001432028526/ 上回我们分析到QPushButton的初始化,知道了Wi ...