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 ...
随机推荐
- [Effective JavaScript 笔记]第61条:不要阻塞I/O事件队列
js程序是构建在事件之上的.输入可能来自不同的外部源.在一些语言中,我们习惯地编写代码来等待某个特定的输入. var text=downloadSync('http://example.com/fil ...
- Unity3d iOS基本优化和高级优化
原地址:http://www.cocoachina.com/bbs/read.php?tid=70395&page=1 分享看见的2篇好文.简单翻译了一下并且放出原文 http://www.c ...
- Linux Haproxy 安装和部署
一.Haproxy 安装 下载地址 http://pan.baidu.com/s/1mggViXE cd /usr/local tar xzvf haproxy-.tar.gz cd haproxy- ...
- 静态资源[org.springframework.web.servlet.PageNotFound]
springmvc 无法访问js.css.jpg等资源文件,tomcat启动报警告如下 [org.springframework.web.servlet.PageNotFound] - No mapp ...
- Missing Ranges & Summary Ranges
Missing Ranges Given a sorted integer array where the range of elements are [lower, upper] inclusive ...
- HTML表单元素Emil和密码
<form action="" method="post" name="myform"><p>E-mail:< ...
- css 属性
部分属性在firefox 中添加-moz- safari 以及chrome 加上-webkit- opera 加上-o- ie9里可能需要-ms- jquery 中的css 操作 和一般的cs ...
- Select Top在不同数据库中的使用
1. oracle数据库 SELECT * FROM TABLE1 WHERE ROWNUM<=N 2. Infomix数据库 SELECT FIRST N * FROM TABLE1 3. D ...
- javascript动态添加一组input
2013年12月18日 20:56:29 场景: 批量添加 友情链接 功能 每个友情链接记录有3个字段:名字(name),超链接(url),排序(order) 要求每次点击"添加" ...
- 9.Python笔记之面向对象高级部分
类的成员 类的成员可以分为三大类:字段.方法和属性 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段.而其他的成员,则都是保存在类中,即:无论对象的 ...