[BZOJ4034][HAOI2015]树上操作 树链剖分
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4034
轻重链剖分,重儿子先行。树剖模版题。
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(){ 101 N=readint(); 102 M=readint(); 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++){ 106 int a=readint(), 107 b=readint(); 108 Add(a,b); 109 Add(b,a); 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++){ 116 int Opt=readint(), 117 x=readint(),a; 118 switch(Opt){ 119 case 1: 120 a=readint(); 121 Insert(1,N,1,in[x],in[x],a); 122 break; 123 case 2: 124 a=readint(); 125 Insert(1,N,1,in[x],out[x],a); 126 break; 127 case 3: 128 printf("%lld\n",Qry(x)); 129 break; 130 } 131 } 132 return 0; 133 }