继续链剖

因为子树在区间上连续,所以记最后一个位置即可

线段树不熟了。。。没注意用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 }
View Code

 

posted on 2015-12-12 19:44  onlyRP  阅读(157)  评论(0编辑  收藏  举报