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. 《javascript模式--by Stoyan Stefanov》书摘--基本技巧

    一.基本技巧 1,变量释放的副作用 a.使用var创建的全局变量(在函数外部创建)不能删除. b.不使用var创建的隐含全局变量(尽管在函数内部创建)可以删除. // 定义三个全局变量 var glo ...

  2. 使用 letter-space 后文字不能居中解决

    letter-space:2em; text-align: center; 使用letter-space后和上面的字体对比明显没有居中: 选定元素后发现,每个字后面都被加了2em,不是不能居中而是因为 ...

  3. c# 计算两个时间的时间差

    //计算2个日期之间的天数差 DateTime dt1 = Convert.ToDateTime("2007-8-1"); DateTime dt2 = Convert.ToDat ...

  4. 软工1816 · Alpha冲刺(3/10)

    团队信息 队名:爸爸饿了 组长博客:here 作业博客:here 组员情况 组员1(组长):王彬 过去两天完成了哪些任务 完成了对laravel框架的一整套机制的了解,对后端的处理流程有全面的认识对整 ...

  5. 统一日志系统 Log4Net/ExceptionLess

    一.   写在前面 本文Log4Net介绍了基础的方式,大数据量生产环境不能使用,中等日志量请日志单库. 希望爱技术的你不要错过exceptionless和ELK 第四节开始简单配置大牛们推荐的了Ex ...

  6. New API

    New API Producer >增加发送回调 >重构Partition 统一High Level API与Low Level API >从kafka.consumer和kafka ...

  7. WPF实例,以getFiles()获取文件夹,treeview的应用

    读取电脑硬盘根目录添加到TreeView控件 foreach (DriveInfo item in System.IO.DriveInfo.GetDrives()) { if(item.ToStrin ...

  8. 【Python】python文件名和文件路径操作

    Readme: 在日常工作中,我们常常涉及到有关文件名和文件路径的操作,在python里的os标准模块为我们提供了文件操作的各类函数,本文将分别介绍“获得当前路径”“获得当前路径下的所有文件和文件夹, ...

  9. Keil MDK中Image~~RW_IRAM1~~ZI~~Limit(~表示$)

    ARM程序的组成 此处所说的“ARM程序”是指在ARM系统中正在执行的程序,而非保存在ROM中的bin映像(image)文件,这一点清注意区别.            一个ARM程序包含3部分:RO, ...

  10. 【bzoj4008】[HNOI2015]亚瑟王 概率dp

    题目描述 $n$ 张牌,$r$ 轮游戏,每轮从左向右操作,遇到第 $i$ 张牌有 $p_i$ 的概率选中,选中会产生 $d_i$ 的贡献,丢弃掉该牌并结束这一轮,否则继续下一张.问最终的期望贡献. 输 ...