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;
}

  

时间: 2024-10-26 14:52:40

BZOJ4389 : ZYB and Trees的相关文章

LeetCode OJ :Unique Binary Search Trees II(唯一二叉搜索树)

题目如下所示:返回的结果是一个Node的Vector: Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. For example,Given n = 3, your program should return all 5 unique BST's shown below. 1 3 3 2 1 \ / / / \ 3 2 1 1 3 2 / / \ 2 1 2

HDOJ 4010 Query on The Trees LCT

LCT: 分割.合并子树,路径上全部点的点权添加一个值,查询路径上点权的最大值 Query on The Trees Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) Total Submission(s): 2582    Accepted Submission(s): 1208 Problem Description We have met so many problems

96. Unique Binary Search Trees

Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For example,Given n = 3, there are a total of 5 unique BST's. 1 3 3 2 1 \ / / / \ 3 2 1 1 3 2 / / \ 2 1 2 3 对1-n组成的BST,如果选定i为根,那1-(i-1)都在根的左子树里,(i+1)-n都在根的右子树里

[leetcode-95-Unique Binary Search Trees II]

Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1...n. For example,Given n = 3, your program should return all 5 unique BST's shown below. 1 3 3 2 1 \ / / / \ 3 2 1 1 3 2 / / \ 2 1 2 3 思路: This probl

Unique Binary Search Trees I &amp; II

Given n, how many structurally unique BSTs (binary search trees) that store values 1...n? Example Given n = 3, there are a total of 5 unique BST's. 1 3 3 2 1 \ / / / \ 3 2 1 1 3 2 / / \ 2 1 2 3 分析: 当数组为 1,2,3,4,.. i,.. n时,基于以下原则的BST建树具有唯一性:以i为根节点的树,其

leetcode95 Unique Binary Search Trees II

题目: Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. For example,Given n = 3, your program should return all 5 unique BST's shown below. 思路: 本题采取递归的思路. 传递的参数是开始数值(begin)和结束数值(end). 当begin > end 时,返回空(注意不是

Unique Binary Search Trees

Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For example,Given n = 3, there are a total of 5 unique BST's. 1 3 3 2 1 \ / / / \ 3 2 1 1 3 2 / / \ 2 1 2 3 终于开始动态规划的题目了.这道题目需要耐心挖掘其中的规律,首先根不一样的二叉搜索树肯定是不同的搜索树.

uva 122 trees on the level——yhx

题目如下:Given a sequence of binary trees, you are to write a program that prints a level-order traversal of each tree. In this problem each node of a binary tree contains a positive integer and all binary trees have have fewer than 256 nodes. In a level

ZYB&#39;s Premutation(有逆序数输出原序列,线段树)

ZYB's Premutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 758    Accepted Submission(s): 359 Problem Description ZYB has a premutation P,but he only remeber the reverse log of each pr