stO
树链剖分
Orz
\color{red}\text{stO} \color{orange}\text{树链剖分}\color{green}\text{Orz}
stO树链剖分Orz
蛤 HaOI tql
#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>#define maxn 444444#define int long long usingnamespace std ;struct dy{int x , y , z , next ;}a[maxn];struct Tree {int lc,rc,sum,tag ;}tree[maxn];int deep[maxn], top[maxn], id[maxn], size[maxn],son[maxn];int n , m , r , p ;int tot , cnt =1;int head[maxn], fa[maxn], w[maxn],wt[maxn], tt ;voidpushup(int u){
tree[u].sum =(tree[tree[u].lc].sum + tree[tree[u].rc].sum);return;}voidpushdown(int u ,int l ,int r){int mid =(l+r)>>1;
tree[tree[u].lc].sum =(tree[tree[u].lc].sum+(mid-l+1)*tree[u].tag);
tree[tree[u].lc].tag =(tree[u].tag+tree[tree[u].lc].tag);
tree[tree[u].rc].sum =(tree[tree[u].rc].sum + tree[u].tag*(r-mid));
tree[tree[u].rc].tag =(tree[tree[u].rc].tag+tree[u].tag);
tree[u].tag =0;return;}voidbuild(int u ,int l ,int r){if(l == r){
tree[u].sum = wt[l];return;}int mid =(l+r)>>1;
tree[u].lc =++cnt ;build(tree[u].lc,l,mid);
tree[u].rc =++cnt ;build(tree[u].rc , mid+1,r);pushup(u);}intquery(int u ,int l ,int r,int ll,int rr){if(l == ll && r == rr){return tree[u].sum ;}int mid =(l+r)>>1;pushdown(u,l,r);if(rr <= mid)returnquery(tree[u].lc,l,mid,ll,rr);elseif(ll > mid)returnquery(tree[u].rc,mid+1,r,ll,rr);else{return(query(tree[u].lc,l,mid,ll,mid)+query(tree[u].rc,mid+1,r,mid+1,rr));}pushup(u);}voidupdata(int u ,int l ,int r,int ll ,int rr,int w){if(l == ll &&r == rr){
tree[u].sum =(tree[u].sum + w*(r-l+1));
tree[u].tag =(tree[u].tag + w);return;}int mid =(l+r)>>1;pushdown(u,l,r);if(rr <= mid)updata(tree[u].lc,l,mid,ll,rr,w);elseif(ll > mid)updata(tree[u].rc,mid+1,r,ll,rr,w);else{updata(tree[u].lc,l,mid,ll,mid,w);updata(tree[u].rc,mid+1,r,mid+1,rr,w);}pushup(u);}voiddfs1(int x,int f,int depth){
size[x]=1;
fa[x]= f ;
deep[x]= depth ;for(int i = head[x]; i ; i = a[i].next){int v = a[i].y ;if(v == f )continue;dfs1(v,x,depth+1);
size[x]+= size[v];if(size[v]> size[son[x]]){
son[x]= v ;}}}voiddfs2(int x,int topf){
id[x]=++ tt ;
wt[tt]= w[x];
top[x]= topf;if(!son[x])return;dfs2(son[x],topf);for(int i = head[x]; i ; i = a[i].next){int v = a[i].y;if(v == son[x]|| v == fa[x])continue;dfs2(v,v);}}intqlink(int x,int y){int ans =0;while(top[x]!= top[y]){if(deep[top[x]]< deep[top[y]])swap(x,y);
ans +=query(1,1,n,id[top[x]],id[x]);
x = fa[top[x]];}if(deep[x]> deep[y])swap(x,y);
ans =(ans +query(1,1,n,id[x],id[y]));return ans;}voiduplink(int x,int y,int w){while(top[x]!= top[y]){if(deep[top[x]]< deep[top[y]])swap(x,y);updata(1,1,n,id[top[x]],id[x],w);
x = fa[top[x]];}if(deep[x]> deep[y])swap(x,y);updata(1,1,n,id[x],id[y],w);}intqson(int x){returnquery(1,1,n,id[x],id[x]+size[x]-1);}voidupson(int x,int w){updata(1,1,n,id[x],id[x]+size[x]-1,w);}voidadd(int x ,int y){
a[++tot].x = x ;
a[tot].y = y ;
a[tot].next = head[x];
head[x]= tot ;}signed main (){
cin >> n >> m ;for(int i =1; i <= n ; i ++)
cin >> w[i];for(int i =1; i < n ; i ++){int x,y;
cin >> x >> y ;add(x,y);add(y,x);}dfs1(1,0,1);dfs2(1,1);build(1,1,n);while(m --){int opt;
cin >> opt ;if(opt ==1){int x,y,z;
cin >> x >> y ;updata(1,1,n,id[x],id[x],y);}if(opt ==2){int x,y;
cin >> x >> y ;upson(x,y);}if(opt ==3){int x,z;
cin >> x ;
cout <<qlink(1,x)<< endl ;}}return0;}