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的更多相关文章

  1. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  2. [C#] C# 知识回顾 - 表达式树 Expression Trees

    C# 知识回顾 - 表达式树 Expression Trees 目录 简介 Lambda 表达式创建表达式树 API 创建表达式树 解析表达式树 表达式树的永久性 编译表达式树 执行表达式树 修改表达 ...

  3. hdu2848 Visible Trees (容斥原理)

    题意: 给n*m个点(1 ≤ m, n ≤ 1e5),左下角的点为(1,1),右上角的点(n,m),一个人站在(0,0)看这些点.在一条直线上,只能看到最前面的一个点,后面的被档住看不到,求这个人能看 ...

  4. [LeetCode] Minimum Height Trees 最小高度树

    For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...

  5. [LeetCode] Unique Binary Search Trees 独一无二的二叉搜索树

    Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For examp ...

  6. [LeetCode] Unique Binary Search Trees II 独一无二的二叉搜索树之二

    Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. For e ...

  7. 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 ...

  8. 线段树 - ZYB's Premutation

    ZYB has a premutation P,but he only remeber the reverse log of each prefix of the premutation,now he ...

  9. 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 ...

随机推荐

  1. 在Mysql中如何显示所有用户?

    这是一个mysql初学者经常问到的一个问题,今天我们就带大家看看是如何在Mysql中显示所有用户的.通常我们在mysql中使用SHOW DATABASES可以显示所有的数据库,SHOW TABLES将 ...

  2. ios反射

    http://www.cr173.com/html/18677_1.html 1.反射获取类属性名和属性类型 unsigned ; objc_property_t *properties = clas ...

  3. retain copy(浅复制) mutablecopy (深复制)

    http://blog.csdn.net/xdrt81y/article/details/24331103   口诀: 1浅3深   NSArray copy (浅) 返回NSArray NSArra ...

  4. 更改win7开机界面

    按“win+R”组合键,打开运行框,在打开框中输入"regedit”,单击“确定”. 打开注册表编辑器,依次展开注册表里: “HKEY_LOCAL_MACHINE---SOFTWARE--- ...

  5. Hibernate与 MyBatis的比较

    希望大家指出不对之处. 第一章     Hibernate与MyBatis Hibernate 是当前最流行的O/R mapping框架,它出身于sf.net,现在已经成为Jboss的一部分. Myb ...

  6. 更改SharePoint 2010 顶部导航为下拉菜单样式

      更改SharePoint 2010 顶部导航为下拉菜单样式 最后的效果图: 假如一个网站集顶级站点下面有子网站:sub site1,该子站点下面又有两个子站点:sub site1_1,sub si ...

  7. 转mysql存储引擎memory,ndb,innodb之选择

    1 mysql的innodb和cluster的NDB引擎都支持事务,在有共同的特性外,也有不同之处:以mysql cluster NDB 7.3和MySQL 5.6之InnoDB为例:ndb7.3基于 ...

  8. Java如何读取XML文件 具体实现

    转载自:http://www.jb51.net/article/44338.htm import java.io.*; import javax.xml.parsers.DocumentBuilder ...

  9. [Android Pro] Android fastboot刷机和获取Root权限

    参考文章: https://developers.google.com/android/nexus/images 转载自:    http://www.inexus.co/article-1280-1 ...

  10. 如何在Win8系统上建立WIFI热点

    1.首先将鼠标移到桌面左下角,单击右键,在弹出的快捷菜单中找到“命令提示符(管理员)”,点击 2.点击后,系统就以管理员权限打开了命令提示符,在命令提示符中输入以下命令“netsh wlan set ...