[BZOJ4034][HAOI2015]树上操作(树链剖分+线段树)

模板题,注意long long。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define ls (x<<1)
 5 #define rs (ls|1)
 6 #define lson ls,L,mid
 7 #define rson rs,mid+1,R
 8 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 9 #define For(i,x) for (int i=h[x],k; i; i=nxt[i])
10 typedef long long ll;
11 using namespace std;
12 
13 const int N=100010;
14 int n,m,u,v,cnt,tim,op,x,k,a[N],L[N],R[N],son[N],sz[N];
15 int dep[N],fa[N],top[N],h[N],nxt[N<<1],to[N<<1];
16 ll sm[N<<2],tag[N<<2];
17 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
18 
19 void push(int x,int L,int R){
20     if (!tag[x]) return;
21     int mid=(L+R)>>1;
22     sm[ls]+=tag[x]*(mid-L+1); tag[ls]+=tag[x];
23     sm[rs]+=tag[x]*(R-mid); tag[rs]+=tag[x];
24     tag[x]=0;
25 }
26 
27 void ins(int x,int L,int R,int l,int r,int k){
28     if (L==l && r==R){ sm[x]+=1ll*k*(R-L+1); tag[x]+=k; return; }
29     int mid=(L+R)>>1; push(x,L,R);
30     if (r<=mid) ins(lson,l,r,k);
31     else if (l>mid) ins(rson,l,r,k);
32         else ins(lson,l,mid,k),ins(rson,mid+1,r,k);
33     sm[x]=sm[ls]+sm[rs];
34 }
35 
36 ll que(int x,int L,int R,int l,int r){
37     if (L==l && r==R) return sm[x];
38     int mid=(L+R)>>1; push(x,L,R);
39     if (r<=mid) return que(lson,l,r);
40     else if (l>mid) return que(rson,l,r);
41         else return que(lson,l,mid)+que(rson,mid+1,r);
42 }
43 
44 void dfs1(int x){
45     sz[x]=1; dep[x]=dep[fa[x]]+1;
46     For(i,x) if ((k=to[i])!=fa[x]){
47         fa[k]=x; dfs1(k); sz[x]+=sz[k];
48         if (sz[k]>sz[son[x]]) son[x]=k;
49     }
50 }
51 
52 void dfs2(int x,int tp){
53     L[x]=++tim; top[x]=tp;
54     if (son[x]) dfs2(son[x],tp);
55     For(i,x) if ((k=to[i])!=fa[x] && k!=son[x]) dfs2(k,k);
56     R[x]=tim;
57 }
58 
59 void solve(int x){
60     ll res=0;
61     while (top[x]!=1) res+=que(1,1,n,L[top[x]],L[x]),x=fa[top[x]];
62     res+=que(1,1,n,1,L[x]); printf("%lld\n",res);
63 }
64 
65 int main(){
66     freopen("bzoj4034.in","r",stdin);
67     freopen("bzoj4034.out","w",stdout);
68     scanf("%d%d",&n,&m);
69     rep(i,1,n) scanf("%d",&a[i]);
70     rep(i,2,n) scanf("%d%d",&u,&v),add(u,v),add(v,u);
71     dfs1(1); dfs2(1,1);
72     rep(i,1,n) ins(1,1,n,L[i],L[i],a[i]);
73     rep(i,1,m){
74         scanf("%d",&op);
75         if (op==1) scanf("%d%d",&x,&k),ins(1,1,n,L[x],L[x],k);
76         if (op==2) scanf("%d%d",&x,&k),ins(1,1,n,L[x],R[x],k);
77         if (op==3) scanf("%d",&x),solve(x);
78     }
79     return 0;
80 }

 

posted @ 2018-11-01 18:32  HocRiser  阅读(102)  评论(0编辑  收藏  举报