BZOJ 3786: 星系探索 欧拉游览树
一个叫 Euler-Tour-Tree 的数据结构,说白了就是用 Splay_Tree 维护欧拉序
#include <cstring> #include <algorithm> #include <string> #include <cstdio> using namespace std; void setIO(string a){ freopen((a+".in").c_str(),"r",stdin); freopen((a+".out").c_str(),"w",stdout); } #define maxn 300000 #define ll long long int euler[maxn], w[maxn], cnt=1; int head[maxn],to[maxn],nex[maxn],edges,root; ll sumv[maxn], val[maxn], lazy[maxn]; void addedge(int u,int v){ nex[++edges]=head[u],head[u]=edges,to[edges]=v; } void dfs(int u){ euler[++cnt]=u*2, val[u*2]=w[u]; for(int v=head[u];v;v=nex[v]) dfs(to[v]); euler[++cnt]=u*2+1, val[u*2+1]=-w[u]; } struct Splay_Tree{ int f[maxn],ch[maxn][2],sta[maxn],siz[maxn]; int rson(int x) { return ch[x][1]; } int lson(int x) { return ch[x][0]; } int get(int x) { return ch[f[x]][1]==x; } void update(int x,int c) { val[x]+=(x%2==0?1:-1)*c; lazy[x]+=c; sumv[x]+=siz[x]*c; } void pushup(int x) { sumv[x]=sumv[lson(x)]+sumv[rson(x)]+val[x]; siz[x]=siz[lson(x)]+siz[rson(x)]; siz[x]+=(x>=200099 ? 0: (x%2==0?1:-1)); } void pushdown(int x) { if(lazy[x]) update(lson(x),lazy[x]), update(rson(x),lazy[x]),lazy[x]=0; } int pre(int x) { splay(x,root); x=lson(root); while(rson(x)) x=rson(x); return x; } int las(int x) { splay(x,root); x=rson(root); while(lson(x)) x=lson(x); return x; } void build(int l,int r,int &o,int fa) { if(l>r)return; int mid=(l+r)>>1; o=euler[mid], f[o]=fa; build(l,mid-1,ch[o][0],o); build(mid+1,r,ch[o][1],o); pushup(o); } void rotate(int x) { int old=f[x], oldf=f[old], which=get(x); ch[old][which]=ch[x][which^1], f[ch[old][which]]=old; ch[x][which^1]=old,f[old]=x,f[x]=oldf; if(oldf) ch[oldf][ch[oldf][1]==old]=x; pushup(old),pushup(x); } void splay(int x,int &tar) { int v=0,u=x,a=f[tar]; while(u!=a) sta[++v]=u,u=f[u]; while(v) pushdown(sta[v--]); for(int fa;(fa=f[x])!=a;rotate(x)) if(f[fa]!=a) rotate(get(fa)==get(x)?fa:x); tar=x; } void opt1(int a) { int x=las(a*2); splay(200100,root),splay(x,ch[root][1]); printf("%lld\n",sumv[ch[ch[root][1]][0]]); } void opt2(int a,int b) { int x=pre(a*2),y=las(a*2+1),tmp; splay(x,root),splay(y,ch[root][1]); tmp=ch[ch[root][1]][0], ch[ch[root][1]][0]=f[tmp]=0; pushup(ch[root][1]), pushup(root); x=las(b*2); splay(b*2,root), splay(x,ch[root][1]); ch[ch[root][1]][0]=tmp,f[tmp]=ch[root][1]; pushup(ch[root][1]),pushup(root); } void opt3(int a,int b) { int x=pre(a*2),y=las(a*2+1); splay(x,root),splay(y,ch[root][1]); update(ch[ch[root][1]][0],b); pushup(ch[root][1]),pushup(root); } }tree; int main(){ //setIO("input"); int n,x,m; scanf("%d",&n); for(int i=2;i<=n;++i) scanf("%d",&x),addedge(x,i); for(int i=1;i<=n;++i) scanf("%d",&w[i]); dfs(1); euler[1]=200100, euler[++cnt]=200101; tree.build(1,cnt,root,0); scanf("%d",&m); while(m--) { char opt[10]; int a,b; scanf("%s",opt); if(opt[0]=='Q') { scanf("%d",&a); tree.opt1(a); } if(opt[0]=='C') { scanf("%d%d",&a,&b); tree.opt2(a,b); } if(opt[0]=='F') { scanf("%d%d",&a,&b); tree.opt3(a,b); } } return 0; }
BZOJ 3786: 星系探索 欧拉游览树的更多相关文章
- 数据结构&图论:欧拉游览树
ETT可以称为欧拉游览树,它是一种和欧拉序有关的动态树(LCT是解决动态树问题的一种方案,这是另一种) dfs序和欧拉序是把树问题转化到区间问题上然后再用数据结构去维护的利器 通过借助这两种形式能够完 ...
- BZOJ 3786: 星系探索 解题报告
3786: 星系探索 Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅 ...
- BZOJ 3786 星系探索
Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球 ...
- BZOJ 3786: 星系探索 [伪ETT]
传送门 数据,标程 题意: 一颗有根树,支持询问点到根路径权值和,子树加,换父亲 欧拉序列怎么求路径权值和? 一个点的权值只会给自己的子树中的点贡献,入栈权值正出栈权值负,求前缀和就行了! 和上题一样 ...
- bzoj 3786 星系探索 dfs+splay
[BZOJ3786]星系探索 Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球 ...
- BZOJ 3786 星系探索 (splay+dfs序)
题目大意:给你一棵树,支持一下三种操作 1.获取某节点到根节点的路径上所有节点的权值和 2.更换某棵子树的父亲 3.某子树内所有节点的权值都增加一个值w 当时想到了splay维护dfs序,查完题解发现 ...
- BZOJ 3786: 星系探索 ETT
Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球 ...
- BZOJ 3786 星系探索 ——Splay
子树可以移动,唔. 还是用Splay维护DFS序即可. 子树的话直接截取出来就好了. 然后求前驱后继可能麻烦一些. 添加两个虚拟节点会比较好写. #include <map> #inclu ...
- BZOJ 2818 Gcd 线性欧拉
题意:链接 方法:线性欧拉 解析: 首先列一下表达式 gcd(x,y)=z(z是素数而且x,y<=n). 然后我们能够得到什么呢? gcd(x/z,y/z)=1; 最好还是令y>=x 则能 ...
随机推荐
- iOS-UITextField 全面解析
iOS中UITextField 使用全面解析 建议收藏,用到的时候来这里一查就都明白了 //初始化textfield并设置位置及大小 UITextField *text = [[UITextField ...
- JQuery实现的弹窗效果
这是笔者实际项目中的一个需求,我们先来看看特效. 页面加载时弹出窗口,点击关闭按钮,窗口消失并呈现动画效果. 实现代码如下: <!DOCTYPE HTML PUBLIC "-//W3C ...
- LeetCode 744. Find Smallest Letter Greater Than Target (时间复杂度O(n))
题目 太简单了,直接上代码: class Solution { public: char nextGreatestLetter(vector<char>& letters, cha ...
- 51nod 1065 最小正字段和 解决办法:set存前缀和,二分插入和二分查找
题目: 这题要求大于0的最小字段和,常规O(n)求最大字段和的方法肯定是没法解的. 我的解法是:用sum[i]存前i项的和,也就是前缀和. 这题就变成了求sum[j]-sum[i]的大于0的最小值( ...
- SQL语句调优相关方法
SQL语句慢的原因:1,数据库表的统计信息不完整2,like查询估计不准确调优方法:1,查看表中数据的条数:2, explain analyze target_SQL;查看SQL执行计划:比较SQL总 ...
- 正则表达式中的/i
i = insensitive means case-insensitive 表示大小写不敏感
- LightOJ-1220 Mysterious Bacteria 唯一分解定理 带条件的最大公因数
题目链接:https://cn.vjudge.net/problem/LightOJ-1220 题意 给x=y^p,问p最大多少 注意x可能负数 思路 唯一分解定理,求各素因数指数的GCD 注意负数的 ...
- POJ 3261 Milk Patterns(后缀数组+单调队列)
题意 找出出现k次的可重叠的最长子串的长度 题解 用后缀数组. 然后求出heigth数组. 跑单调队列就行了.找出每k个数中最小的数的最大值.就是个滑动窗口啊 (不知道为什么有人写二分,其实写啥都差不 ...
- jquery复制到剪贴板
<!DOCTYPE html> <html> <head> <title>ZeroClipboard Test</title> <me ...
- Centos6.6 系统优化
1:最小化安装 2:修改网卡 vim /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0HWADDR=52:54:00:0e:c2:c3TYPE ...