# [BZOJ4034][HAOI2015]树上操作 树链剖分

  1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 using namespace std;
5 typedef long long ll;
6 int inline readint(){
7     int Num=0,Flag=1;char ch;
8     while((ch=getchar())<'0'||ch>'9') if(ch=='-') break;
9     if(ch=='-') Flag=-1; else Num=ch-'0';
10     while((ch=getchar())>='0'&&ch<='9') Num=Num*10+ch-'0';
11     return Num*Flag;
12 }
13 int N,M,A[100010];
14 int to[200010],ne[200010],fir[100010],cnt=0;
15 void Add(int a,int b){
16     to[++cnt]=b;
17     ne[cnt]=fir[a];
18     fir[a]=cnt;
19 }
20 int siz[100010],fa[100010],dep[100010],son[100010];
21 void Dfs1(int x){
22     siz[x]=1;
23     son[x]=0;
24     for(int i=fir[x];i!=-1;i=ne[i]){
25         int v=to[i];
26         if(v!=fa[x]){
27             fa[v]=x;
28             dep[v]=dep[x]+1;
29             Dfs1(v);
30             siz[x]+=siz[v];
31             if(siz[v]>siz[son[x]]) son[x]=v;
32         }
33     }
34 }
35 int top[100010],in[100010],out[100010],dfn=0;
36 void Dfs2(int x){
37     in[x]=++dfn;
38     if(!son[x]){
39         out[x]=dfn;
40         return;
41     }
42     top[son[x]]=top[x];
43     Dfs2(son[x]);
44     for(int i=fir[x];i!=-1;i=ne[i]){
45         int v=to[i];
46         if(v!=fa[x]&&v!=son[x]){
47             top[v]=v;
48             Dfs2(v);
49         }
50     }
51     out[x]=dfn;
52 }
53 #define lson l,mid,rt<<1
54 #define rson mid+1,r,rt<<1|1
55 ll sum[400010],col[400010];
56 void inline Pushup(int &rt){
57     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
58 }
59 void inline Pushdown(int &rt,int len){
60     if(col[rt]){
61         sum[rt<<1]+=col[rt]*(len-(len>>1));
62         sum[rt<<1|1]+=col[rt]*(len>>1);
63         col[rt<<1]+=col[rt];
64         col[rt<<1|1]+=col[rt];
65         col[rt]=0;
66     }
67 }
68 void Insert(int l,int r,int rt,int L,int R,ll x){
69     if(L<=l&&r<=R){
70         col[rt]+=x;
71         sum[rt]+=x*(r-l+1);
72         return;
73     }
74     Pushdown(rt,r-l+1);
75     int mid=l+r>>1;
76     if(L<=mid) Insert(lson,L,R,x);
77     if(R>mid) Insert(rson,L,R,x);
78     Pushup(rt);
79 }
80 ll Qsum(int l,int r,int rt,int L,int R){
81     if(L<=l&&r<=R) return sum[rt];
82     Pushdown(rt,r-l+1);
83     int mid=l+r>>1;
84     ll ret=0;
85     if(L<=mid) ret=Qsum(lson,L,R);
86     if(R>mid) ret+=Qsum(rson,L,R);
87     return ret;
88 }
89 ll Qry(int x){
90     ll ret=0;
91     int tx=top[x];
92     while(tx!=1){
93         ret+=Qsum(1,N,1,in[tx],in[x]);
94         x=fa[tx];
95         tx=top[x];
96     }
97     ret+=Qsum(1,N,1,in[tx],in[x]);
98     return ret;
99 }
100 int main(){
103     for(int i=1;i<=N;i++) A[i]=readint();
104     memset(fir,-1,sizeof(fir));
105     for(int i=1;i<N;i++){
110     }
111     Dfs1(1);
112     top[1]=1;
113     Dfs2(1);
114     for(int i=1;i<=N;i++) Insert(1,N,1,in[i],in[i],A[i]);
115     for(int i=1;i<=M;i++){
118         switch(Opt){
119             case 1:
121                 Insert(1,N,1,in[x],in[x],a);
122                 break;
123             case 2:
133 }