树链剖分学习笔记

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\n",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\n",que(1,1,n,pos[x],rps[x]));
104         }
105     }
106     return 0;
107 }

 

posted on 2017-05-22 15:33  whz2002  阅读(138)  评论(0编辑  收藏  举报