考前复习模板题(子树修改,单点修改,链上求和)。
一晚上狂TLE,原因竟是:链剖siz比较写错,写了个轻链剖分。。。
#include<bits/stdc++.h>
using namespace std;
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define root 1,1,n
typedef long long ll;
const int MAXN=1e5+4;
int n,m,a[MAXN];
vector<int > g[MAXN];
int fa[MAXN],dep[MAXN],siz[MAXN],son[MAXN],top[MAXN],in[MAXN],out[MAXN],rk[MAXN],tim=0;
/*------------DCP------------*/
void dfs1(int p,int father,int d) {
siz[p]=1,dep[p]=d,fa[p]=father;
for (int i=0;i<g[p].size();++i) {
int v=g[p][i];
if (v^father) {
dfs1(v,p,d+1);
siz[p]+=siz[v];
if (son[p]==-1||siz[v]>siz[son[p]])
son[p]=v;
}
}
}
void dfs2(int p,int tp) {
top[p]=tp,in[p]=++tim,rk[tim]=p;
if (~son[p]) dfs2(son[p],tp);
for (int i=0;i<g[p].size();++i) {
int v=g[p][i];
if (v^fa[p]&&v^son[p])
dfs2(v,v);
}
out[p]=tim;
}
/*------------Segment Tree------------*/
ll sum[MAXN<<2],laz[MAXN<<2];
void build(int rt,int l,int r) {
laz[rt]=0;
if (l==r) {sum[rt]=a[rk[l]];return ;}
int mid=l+r>>1;
build(lson);
build(rson);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
inline void pushdown(int rt,int len) {
if (laz[rt]) {
laz[rt<<1]+=laz[rt];
laz[rt<<1|1]+=laz[rt];
sum[rt<<1]+=laz[rt]*(len-(len>>1));
sum[rt<<1|1]+=laz[rt]*(len>>1);
laz[rt]=0;
}
}
void modify(int rt,int l,int r,int L,int R,ll val) {
if (L<=l&&r<=R) {
sum[rt]+=val*(r-l+1);
laz[rt]+=val;
return ;
}
pushdown(rt,r-l+1);
int mid=l+r>>1;
if (L<=mid) modify(lson,L,R,val);
if (mid<R) modify(rson,L,R,val);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
ll query(int rt,int l,int r,int L,int R) {
if (L<=l&&r<=R) return sum[rt];
pushdown(rt,r-l+1);
int mid=l+r>>1;
ll ret=0;
if (L<=mid) ret+=query(lson,L,R);
if (mid<R) ret+=query(rson,L,R);
return ret;
}
ll ask(int x,int y) {
ll ret=0;
while (top[x]^top[y]) {
if (dep[top[x]]<dep[top[y]]) x^=y^=x^=y;
ret+=query(root,in[top[x]],in[x]);
x=fa[top[x]];
}
if (dep[x]<dep[y]) x^=y^=x^=y;
ret+=query(root,in[y],in[x]);
return ret;
}
inline int read() {
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x*f;
}
int main() {
// freopen("bzoj 4034.in","r",stdin);
memset(son,-1,sizeof(son));
n=read(),m=read();
for (register int i=1;i<=n;++i) a[i]=read(),g[i].clear();
for (register int i=1;i<n;++i) {
int u=read(),v=read();
g[u].push_back(v);
g[v].push_back(u);
}
dfs1(1,0,1);
dfs2(1,1);
build(root);
for (register int i=0;i<m;++i) {
int opt=read();
switch (opt) {
case 1:{
int x=read();
ll v=read();
modify(root,in[x],in[x],v);
break;
}
case 2:{
int x=read();
ll v=read();
modify(root,in[x],out[x],v);
break;
}
case 3:{
int x=read();
printf("%lld\n",ask(1,x));
break;
}
}
}
return 0;
}