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 ...
随机推荐
- Numeric Validation
Numeric Inputs Numbers are even easier to validate than text. For number input types, the HTML5 spec ...
- [BZOJ3343]教主的魔法
[BZOJ3343]教主的魔法 试题描述 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.… ...
- 配置oss bucket cors
到bucket中属性中选择跨越设置,点击添加规则会看到以下界面: 对应的输入如上即可.
- HDOJ 1874
畅通工程续 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Subm ...
- Java和PyPy速度对比
Java和PyPy运行同一段代码,对比结果. Java代码: package javatest; import java.text.DecimalFormat; import java.util.Da ...
- ubuntu14.04 中国源
deb http://cn.archive.ubuntu.com/ubuntu/ trusty main restricted universe multiversedeb http://cn.arc ...
- Python egg
http://blog.csdn.net/turkeyzhou/article/details/8876658
- TypeError: document.formname.submit is not a function
<form name="formname" ...> .... <input name="submit" type="submit& ...
- PHP exit() 输出
2014年8月6日 10:41:00 exit($a); 当$a是bool类型,整形的时候,浏览器里是看不到任何输出的 当$a是字符串的时候浏览器里是可以看到输出的 $a = 1; exit($a); ...
- HDU 4059 容斥原理+快速幂+逆元
E - The Boss on Mars Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64 ...