1.树链剖分
ref:http://blog.csdn.net/acdreamers/article/details/10591443
Code:(luogu 3384)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mid ((l+r)>>1) 5 #define le (x<<1) 6 #define ri ((x<<1)|1) 7 #define MN 100005 8 #define MM (1<<18) 9 using namespace std; 10 inline int in(){ 11 int x=0;bool f=0; char c; 12 for (;(c=getchar())<'0'||c>'9';f=c=='-'); 13 for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0'); 14 return f?-x:x; 15 } 16 struct edge{ 17 int to,next; 18 }e[MN<<1]; 19 int siz[MN],son[MN],dep[MN],top[MN],fa[MN],a[MN],head[MN],pos[MN],rps[MN]; 20 int lazy[MM],sum[MM]; 21 int n,q,rt,mod,dfn,cnt=0,x,y,op,z; 22 inline void ins(int x,int y){ 23 e[++cnt].to=y;e[cnt].next=head[x];head[x]=cnt; 24 } 25 inline void dfs1(int u){ 26 siz[u]=1; 27 for (int i=head[u];i;i=e[i].next){ 28 int v=e[i].to; 29 if (v!=fa[u]){ 30 fa[v]=u;dep[v]=dep[u]+1; 31 dfs1(v);siz[u]+=siz[v]; 32 if (siz[v]>siz[son[u]]) son[u]=v; 33 } 34 } 35 } 36 inline void dfs2(int u,int tp){ 37 top[u]=tp;pos[u]=(++dfn);if (son[u]) dfs2(son[u],tp); 38 for (int i=head[u];i;i=e[i].next){ 39 int v=e[i].to; 40 if (v!=fa[u]&&v!=son[u]) dfs2(v,v); 41 }rps[u]=dfn; 42 } 43 inline void pushdown(int x,int l,int r){ 44 if (l==r||!lazy[x]) return;int M=r-l+1; 45 lazy[le]=(lazy[le]+lazy[x])%mod; 46 lazy[ri]=(lazy[ri]+lazy[x])%mod; 47 sum[le]+=(1ll*((M-(M>>1))%mod)*lazy[x])%mod;sum[le]%=mod; 48 sum[ri]+=(1ll*((M>>1)%mod)*lazy[x])%mod;sum[ri]%=mod;lazy[x]=0; 49 } 50 inline void up(int x){ 51 sum[x]=(sum[le]+sum[ri])%mod; 52 } 53 inline void upd(int x,int l,int r,int a,int b,int v){ 54 if (a<=l&&b>=r) { 55 int M=r-l+1;lazy[x]=(lazy[x]+v)%mod; 56 sum[x]+=(1ll*(M%mod)*v)%mod;sum[x]%=mod;return; 57 }pushdown(x,l,r); 58 if (a<=mid) upd(le,l,mid,a,b,v); 59 if (b>mid) upd(ri,mid+1,r,a,b,v);up(x); 60 } 61 inline int que(int x,int l,int r,int a,int b){ 62 if (a==l&&b==r) return sum[x];pushdown(x,l,r); 63 if (b<=mid) return que(le,l,mid,a,b); 64 if (a>mid) return que(ri,mid+1,r,a,b); 65 return (1ll*que(le,l,mid,a,mid)+que(ri,mid+1,r,mid+1,b))%mod; 66 } 67 inline void update(int x,int y,int val){ 68 while(top[x]!=top[y]){ 69 if (dep[top[x]]>dep[top[y]]) upd(1,1,n,pos[top[x]],pos[x],val),x=fa[top[x]]; 70 else upd(1,1,n,pos[top[y]],pos[y],val),y=fa[top[y]]; 71 } 72 if (dep[x]<dep[y]) upd(1,1,n,pos[x],pos[y],val); 73 else upd(1,1,n,pos[y],pos[x],val); 74 } 75 inline int query(int x,int y){ 76 int ans=0; 77 while(top[x]!=top[y]){ 78 if (dep[top[x]]>dep[top[y]]) ans=(1ll*ans+que(1,1,n,pos[top[x]],pos[x]))%mod,x=fa[top[x]]; 79 else ans=(1ll*ans+que(1,1,n,pos[top[y]],pos[y]))%mod,y=fa[top[y]]; 80 } 81 if (dep[x]<dep[y]) ans=(1ll*ans+que(1,1,n,pos[x],pos[y]))%mod; 82 else ans=(1ll*ans+que(1,1,n,pos[y],pos[x]))%mod;return ans; 83 } 84 int main() 85 { 86 n=in();q=in();rt=in();mod=in(); 87 for (int i=1;i<=n;++i) a[i]=in(),a[i]%=mod; 88 for (int i=1;i<n;++i){ 89 x=in();y=in();ins(x,y);ins(y,x); 90 }fa[rt]=rt;dep[rt]=1;dfs1(rt);dfs2(rt,rt); 91 for (int i=1;i<=n;++i) upd(1,1,n,pos[i],pos[i],a[i]); 92 while(q--){ 93 op=in(); 94 if (op==1){ 95 x=in();y=in();z=in(); 96 z%=mod;update(x,y,z); 97 }else if (op==2){ 98 x=in();y=in();printf("%d ",query(x,y)); 99 }else if (op==3){ 100 x=in();z=in(); 101 z%=mod;upd(1,1,n,pos[x],rps[x],z); 102 }else{ 103 x=in();printf("%d ",que(1,1,n,pos[x],rps[x])); 104 } 105 } 106 return 0; 107 }