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 ...
随机推荐
- Coursera台大机器学习技法课程笔记04-Soft-Margin Support Vector Machine
之前的SVM非常的hard,要求每个点都要被正确的划分,这就有可能overfit,为此引入了Soft SVM,即允许存在被错分的点,将犯的错放在目 标函数中进行优化,非常类似于正则化. 将Soft S ...
- bwa的使用方法
bwa的使用需要两中输入文件: Reference genome data(fasta格式 .fa, .fasta, .fna) Short reads data (fastaq格式 .f ...
- mysql 启动错误
错误提示如下: 150815 20:24:40 mysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended150815 20:2 ...
- asp.net动态输出透明gif图片
要使用asp.net动态输出透明gif图片,也就是用Response.ContentType = "image/GIF". 查了国内几个中文资料都没解决,最后是在一个英文博客上找到 ...
- awk内置字符串函数 awk 格式化输出
i249 ~ # ps -efl|head -1|awk '$2~/S/{print $2}'Si249 ~ # ps -efl|awk '$2~/S/{print $2}'SSSS printf - ...
- 【OpenStack】OpenStack系列8之Nova详解 Neutron详解
Neutron下载安装 下载:git clone -b stable/icehouse https://github.com/openstack/neutron.git pip install -r ...
- 《ASP.NET MVC4 WEB编程》学习笔记------Entity Framework的Database First、Model First和Code Only三种开发模式
作者:张博出处:http://yilin.cnblogs.com Entity Framework支持Database First.Model First和Code Only三种开发模式,各模式的开发 ...
- js 猜数字游戏
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 搭建CAS单点登录服务器
最近公司的一个项目需要用到单点登录的功能,之前对单点登录了解得不多.于是网上找了下单点登录的解决方案,发现CAS是个不错的解决方案.于是搭个环境测试了一下.这里记录下测试的详细步骤. 官网:http: ...
- Android 使用dip单位进行布局的一点知识
先看看怎么算出一个设备的dpi, 其实就是算出对角线上有多少个px,之后除上屏幕尺寸.比如,1280*720 的10.1寸设备,dpi = (sqrt(1280*1280+720*720)) / 1 ...