BZOJ4389 : ZYB and Trees
Link-Cut Tree维护。
每个点x维护以下信息:
v:这个点的点权
s:实链上的信息和
st:子树信息和(不包括链上)
sa:子树+链上的信息和
as:所有虚儿子的sa的和
则有
s[x]=v[x]+s[son[x][0]]+s[son[x][1]]
st[x]=as[x]+st[son[x][0]]+st[son[x][1]]
sa[x]=s[x]+st[x]
在access以及link的时候,涉及到虚实边的切换,在这个时候顺带维护一下as即可。
查询以x为根时y子树信息和的时候,将x作为根,然后access(y),此时答案=as[y]+v[y]。
时间复杂度$O(m\log n)$。
#include<cstdio>
#define N 200010
typedef long long ll;
int n,m,i,op,x,y,z;
int f[N],son[N][2],tmp[N],c[N];bool rev[N];
ll v[N],s[N],mx[N],tc[N],ta[N];
ll st[N],sa[N],as[N];
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
inline void umax(ll&a,ll b){if(a<b)a=b;}
inline void swap(int&a,int&b){int c=a;a=b;b=c;}
inline bool isroot(int x){return !f[x]||son[f[x]][0]!=x&&son[f[x]][1]!=x;}
inline void rev1(int x){if(!x)return;swap(son[x][0],son[x][1]);rev[x]^=1;}
inline void col1(int x,ll y){
if(!x)return;
v[x]=mx[x]=tc[x]=y;
s[x]=y*c[x];
ta[x]=0;
sa[x]=s[x]+st[x];
}
inline void add1(int x,ll y){
if(!x)return;
v[x]+=y;
s[x]+=y*c[x];
mx[x]+=y;
if(tc[x])tc[x]+=y;else ta[x]+=y;
sa[x]=s[x]+st[x];
}
inline void pb(int x){
if(rev[x])rev1(son[x][0]),rev1(son[x][1]),rev[x]=0;
if(tc[x])col1(son[x][0],tc[x]),col1(son[x][1],tc[x]),tc[x]=0;
if(ta[x])add1(son[x][0],ta[x]),add1(son[x][1],ta[x]),ta[x]=0;
}
inline void up(int x){
s[x]=mx[x]=v[x];c[x]=1;
st[x]=as[x];
for(int i=0;i<2;i++){
int y=son[x][i];
if(y){
c[x]+=c[y];
s[x]+=s[y];
umax(mx[x],mx[y]);
st[x]+=st[y];
}
}
sa[x]=s[x]+st[x];
}
inline void rotate(int x){
int y=f[x],w=son[y][1]==x;
son[y][w]=son[x][w^1];
if(son[x][w^1])f[son[x][w^1]]=y;
if(f[y]){
int z=f[y];
if(son[z][0]==y)son[z][0]=x;else if(son[z][1]==y)son[z][1]=x;
}
f[x]=f[y];f[y]=x;son[x][w^1]=y;up(y);
}
inline void splay(int x){
int s=1,i=x,y;tmp[1]=i;
while(!isroot(i))tmp[++s]=i=f[i];
while(s)pb(tmp[s--]);
while(!isroot(x)){
y=f[x];
if(!isroot(y)){if((son[f[y]][0]==y)^(son[y][0]==x))rotate(x);else rotate(y);}
rotate(x);
}
up(x);
}
inline void access(int x){
for(int y=0;x;y=x,x=f[x]){
splay(x);
if(son[x][1])as[x]+=sa[son[x][1]];
if(son[x][1]=y)as[x]-=sa[y];
up(x);
}
}
inline void makeroot(int x){access(x);splay(x);rev1(x);}
inline void link(int x,int y){
makeroot(x);
makeroot(y);
as[y]+=sa[x];
f[x]=y;
access(x);
}
inline void cutf(int x){access(x);splay(x);f[son[x][0]]=0;son[x][0]=0;up(x);}
inline void cut(int x,int y){makeroot(x);cutf(y);}
inline void col(int x,int y,int z){makeroot(x);access(y);splay(y);col1(y,z);}
inline void add(int x,int y,int z){makeroot(x);access(y);splay(y);add1(y,z);}
inline ll chainsum(int x,int y){makeroot(x);access(y);splay(y);return s[y];}
inline ll chainmax(int x,int y){makeroot(x);access(y);splay(y);return mx[y];}
inline ll subtreesum(int x,int y){makeroot(x);access(y);splay(y);return as[y]+v[y];}
int main(){
read(n);
for(i=1;i<=n;i++)read(x),v[i]=s[i]=mx[i]=sa[i]=x,c[i]=1;
for(i=2;i<=n;i++)read(x),link(x,i);
read(m);
while(m--){
read(op),read(x),read(y);
if(op==1)read(z),add(x,y,z);
if(op==2)read(z),col(x,y,z);
if(op==3)printf("%lld\n",subtreesum(x,y));
if(op==4)printf("%lld\n",chainmax(x,y));
if(op==5)printf("%lld\n",chainsum(x,y));
if(op==6)link(x,y);
if(op==7)cut(x,y);
}
return 0;
}
BZOJ4389 : ZYB and Trees的更多相关文章
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- [C#] C# 知识回顾 - 表达式树 Expression Trees
C# 知识回顾 - 表达式树 Expression Trees 目录 简介 Lambda 表达式创建表达式树 API 创建表达式树 解析表达式树 表达式树的永久性 编译表达式树 执行表达式树 修改表达 ...
- hdu2848 Visible Trees (容斥原理)
题意: 给n*m个点(1 ≤ m, n ≤ 1e5),左下角的点为(1,1),右上角的点(n,m),一个人站在(0,0)看这些点.在一条直线上,只能看到最前面的一个点,后面的被档住看不到,求这个人能看 ...
- [LeetCode] Minimum Height Trees 最小高度树
For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...
- [LeetCode] Unique Binary Search Trees 独一无二的二叉搜索树
Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For examp ...
- [LeetCode] Unique Binary Search Trees II 独一无二的二叉搜索树之二
Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. For e ...
- 2 Unique Binary Search Trees II_Leetcode
Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. For e ...
- 线段树 - ZYB's Premutation
ZYB has a premutation P,but he only remeber the reverse log of each prefix of the premutation,now he ...
- Finger Trees: A Simple General-purpose Data Structure
http://staff.city.ac.uk/~ross/papers/FingerTree.html Summary We present 2-3 finger trees, a function ...
随机推荐
- Linux下更好用的帮助命令—cheat
导读 Linux系统中,我们经常会用man命令来帮助查看这个命令的具体用法,man是很强大的,但是英语不好的同学用man用起来可能不那么顺手,自然而然的就出现了cheat命令,cheat命令就是通过简 ...
- MySQL数据库服务器的架设
导读 MySQL数据库是Linux操作系统上用得最多的数据库系统,它可以非常方便的与其它服务器集成在一起,如Apache.Vsftpd.Postfix等.下面介绍RHEL 6平台MySQL数据库服务器 ...
- unity3d camera.culling mask
原地址:http://www.cnblogs.com/88999660/archive/2013/03/14/2959439.html 官方文档对CullingMask的注释只是说了通过位移运算符,可 ...
- 对于(function(){}())和function(){}实例的作用域分析(里面有很多问题……)
今天在群里看到一个问题,让我纠结了好一会.下面是我的分析,感觉里面还有很多问题,关于作用域还是不太理解,希望大家看到问题第一时间反馈给我,看到实在受不了的地方说几句都没关系,谢谢. 请看题: 1.对象 ...
- CI邮箱中SMTP的一些端口
介绍其他几个常用邮箱设置,并以网易126邮箱为例,发图. 一.新浪邮箱(1)新浪邮箱自08年6月分服务器被攻击后开始对pop取件频率进行了严格**,同时新注册的用户需要手动才能开通pop ...
- html标签属性大全
<marquee>...</marquee>普通卷动 <marquee behavior=slide>...</marquee>滑动 <marqu ...
- HDU 5044(2014 ACM-ICPC上海网络赛)
题意:给定一个树形图,节点10^5,有两种操作,一种是把某两点间路径(路径必定唯一)上所有点的权值增加一个固定值. 另一种也是相同操作,不同的是给边加权值.操作次数10^5.求操作过后,每个点和每条边 ...
- project.json
概述 项目相关配置,由原来的cocos2d.js中转移到project.json中,该文件需要与index.html同级,一般建议放在根目录下. 字段说明 debugMode 相当于原来的COCOS2 ...
- August 5th, 2016, Week 32nd, Friday
Life is made up of small pleasures. 生活由各种细小的幸福构成. Don't expect too much. I am not qualified to get m ...
- 【2016-07-11】Qt远程部署失败,提示"没有那个文件或目录"的解决方法
首先明确一下,这里的部署失败与网络连接.ssh/scp/sftp等无关. 一般出现在删除了远端上的可执行文件,而本地程序未做明显改动时远程部署执行的时候. Qt应用程序输出中的提示信息如下: 究其原因 ...