继续链剖
因为子树在区间上连续,所以记最后一个位置即可
线段树不熟了。。。没注意用LL
1 #include<bits/stdc++.h> 2 #define inc(i,l,r) for(i=l;i<=r;i++) 3 #define dec(i,l,r) for(i=l;i>=r;i--) 4 #define link(x) for(edge *j=h[x];j;j=j->next) 5 #define mem(a) memset(a,0,sizeof(a)) 6 #define inf 1e9 7 #define ll long long 8 #define succ(x) (1<<x) 9 #define NM 100000+5 10 using namespace std; 11 int read(){ 12 int x=0,f=1;char ch=getchar(); 13 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 14 while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); 15 return x*f; 16 } 17 struct info{ 18 ll z,s; 19 int size; 20 }T[8*NM],null,_t; 21 struct edge{ 22 int t; 23 edge *next; 24 }e[2*NM],*h[NM],*p=e; 25 int n,m,f[NM],size[NM],d[NM],top[NM],TOP,a[NM],id[NM],_id[NM],tot,last[NM],son[NM]; 26 int _x,_y,l,r; 27 info operator+(const info&x,const info&y){ 28 info f; 29 f.s=x.s+y.s; 30 f.size=x.size+y.size; 31 f.z=0; 32 return f; 33 } 34 void add(int x,int y){ 35 p->t=y;p->next=h[x];h[x]=p;p++; 36 } 37 void pushdown(int i){ 38 if(T[i].z){ 39 T[i<<1].s+=(ll)T[i<<1].size*T[i].z;T[i<<1].z+=T[i].z; 40 T[i<<1|1].s+=(ll)T[i<<1|1].size*T[i].z;T[i<<1|1].z+=T[i].z; 41 T[i].z=0; 42 } 43 } 44 void dfs1(int x){ 45 link(x) 46 if(!f[j->t]){ 47 f[j->t]=x; 48 d[j->t]=d[x]+1; 49 dfs1(j->t); 50 size[x]+=size[j->t]; 51 if(size[j->t]>size[son[x]])son[x]=j->t; 52 } 53 size[x]++; 54 } 55 void dfs2(int x){ 56 top[x]=TOP;id[x]=++tot;_id[tot]=x; 57 if(son[x])dfs2(son[x]); 58 link(x) 59 if(!top[j->t])dfs2(TOP=j->t); 60 last[x]=tot; 61 } 62 void build(int i,int x,int y){ 63 int t=x+y>>1; 64 T[i].size=y-x+1; 65 if(x==y){ 66 T[i].s=a[_id[x]]; 67 return; 68 } 69 build(i<<1,x,t);build(i<<1|1,t+1,y); 70 T[i]=T[i<<1]+T[i<<1|1]; 71 } 72 info query(int i,int x,int y){ 73 int t=x+y>>1; 74 pushdown(i); 75 if(l<=x&&y<=r)return T[i]; 76 if(y<l||r<x)return null; 77 return query(i<<1,x,t)+query(i<<1|1,t+1,y); 78 } 79 void ch(int i,int x,int y){ 80 int t=x+y>>1; 81 pushdown(i); 82 if(l<=x&&y<=r){ 83 T[i].z+=(ll)_y; 84 T[i].s+=(ll)T[i].size*_y; 85 return; 86 } 87 if(y<l||r<x)return; 88 ch(i<<1,x,t);ch(i<<1|1,t+1,y); 89 T[i]=T[i<<1]+T[i<<1|1]; 90 } 91 int main(){ 92 // freopen("data.in","r",stdin); 93 int i; 94 null.s=0; 95 n=read();m=read(); 96 inc(i,1,n)a[i]=read(); 97 inc(i,1,n-1){ 98 _x=read();_y=read(); 99 add(_x,_y);add(_y,_x); 100 } 101 f[1]=1; 102 dfs1(1); 103 dfs2(TOP=1); 104 build(1,1,n); 105 while(m--){ 106 _y=read(); 107 if(_y==3){ 108 _x=read();_t.s=0; 109 while(top[_x]!=1){ 110 l=id[top[_x]];r=id[_x]; 111 _t=_t+query(1,1,n); 112 _x=f[top[_x]]; 113 } 114 l=id[1];r=id[_x]; 115 _t=_t+query(1,1,n); 116 printf("%lld\n",_t.s); 117 }else{ 118 _x=read();l=id[_x]; 119 if(_y==1)r=id[_x];else r=last[_x]; 120 _y=read(); 121 ch(1,1,n); 122 } 123 } 124 return 0; 125 }