zoukankan      html  css  js  c++  java
  • 【模板】树链剖分

    洛谷3384

      1 #include<cstdio>
      2 #include<algorithm>
      3 #define ls (cur<<1)
      4 #define rs (cur<<1|1)
      5 #define len(x) (a[x].r-a[x].l+1)
      6 #define mid ((a[cur].l+a[cur].r)>>1) 
      7 using namespace std;
      8 const int maxn=500010;
      9 int n,m,Mod,k,x,y,z,root,tot=0,num=0;
     10 int v[maxn],pos[maxn],dfn[maxn],dep[maxn],son[maxn],size[maxn],fa[maxn],top[maxn],last[maxn];
     11 struct edge{int to,pre;}e[maxn];
     12 struct tree{int l,r,sum,del;}a[maxn<<2];
     13 inline void read(int &k){
     14     k=0; int f=1; char c=getchar();
     15     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
     16     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
     17     k*=f;
     18 }
     19 inline void MOD(int &k){if (k>=Mod) k-=Mod;}
     20 inline void add(int x,int y){e[++tot].to=y; e[tot].pre=last[x]; last[x]=tot;}
     21 void dfs1(int x){
     22     size[x]=1; dep[x]=dep[fa[x]]+1;
     23     for (int i=last[x],to;i;i=e[i].pre)
     24     if ((to=e[i].to)!=fa[x]){
     25         fa[to]=x; dfs1(to);
     26         size[x]+=size[to];
     27         if (size[to]>size[son[x]]) son[x]=to;
     28     }
     29 }
     30 void dfs2(int x,int tp){
     31     top[x]=tp; dfn[x]=++num; pos[num]=x;
     32     if (son[x]) dfs2(son[x],tp);
     33     for (int i=last[x],to;i;i=e[i].pre)
     34     if ((to=e[i].to)!=fa[x]&&to!=son[x]) dfs2(to,to);
     35 }
     36 void build(int cur,int l,int r){
     37     a[cur].l=l; a[cur].r=r;
     38     if (l<r){
     39         build(ls,l,mid); build(rs,mid+1,r);
     40         a[cur].sum=a[ls].sum+a[rs].sum,MOD(a[cur].sum);
     41     }
     42     else a[cur].sum=v[pos[l]];
     43 }
     44 void pushdown(int cur){
     45     if (a[cur].del==0) return; int D=a[cur].del;
     46     a[ls].del+=D;MOD(a[ls].del); a[ls].sum=(a[ls].sum+len(ls)*D)%Mod;
     47     a[rs].del+=D;MOD(a[rs].del); a[rs].sum=(a[rs].sum+len(rs)*D)%Mod;
     48     a[cur].del=0;
     49 }
     50 void add(int cur,int l,int r,int delta){
     51     if (l<=a[cur].l&&a[cur].r<=r){
     52         a[cur].del=(a[cur].del+delta)%Mod;
     53         a[cur].sum=(a[cur].sum+len(cur)*delta)%Mod; return;  
     54     }
     55     pushdown(cur);
     56     if (l<=mid) add(ls,l,r,delta);
     57     if (r>mid) add(rs,l,r,delta);
     58     a[cur].sum=a[ls].sum+a[rs].sum; MOD(a[cur].sum);
     59 }
     60 int query(int cur,int l,int r){
     61     if (l<=a[cur].l&&a[cur].r<=r) return a[cur].sum;
     62     pushdown(cur); int ret=0;
     63     if (l<=mid) ret+=query(ls,l,r),MOD(ret); 
     64     if (r>mid) ret+=query(rs,l,r),MOD(ret);
     65     return ret;
     66 }
     67 int main(){
     68     read(n); read(m); read(root); read(Mod);
     69     for (int i=1;i<=n;i++) read(v[i]),v[i]%=Mod;
     70     for (int i=1;i<n;i++) read(x),read(y),add(x,y),add(y,x);
     71     dfs1(root); dfs2(root,root); build(1,1,n);
     72     for (int i=1;i<=m;i++){
     73         read(k);
     74         if (k==1){
     75             read(x); read(y); read(z);
     76             while(top[x]!=top[y]){
     77                 if (dep[top[x]]<dep[top[y]]) swap(x,y);
     78                 add(1,dfn[top[x]],dfn[x],z); x=fa[top[x]];
     79             }
     80             if (dep[x]>dep[y]) swap(x,y);
     81             add(1,dfn[x],dfn[y],z);
     82         }
     83         if (k==2){
     84             read(x); read(y); int ans=0;
     85             while(top[x]!=top[y]){
     86                 if (dep[top[x]]<dep[top[y]]) swap(x,y);
     87                 ans+=query(1,dfn[top[x]],dfn[x]); MOD(ans); x=fa[top[x]];
     88             }
     89             if (dep[x]>dep[y]) swap(x,y); ans+=query(1,dfn[x],dfn[y]); MOD(ans);
     90             printf("%d
    ",ans);
     91         } 
     92         if (k==3){
     93             read(x); read(y);
     94             add(1,dfn[x],dfn[x]+size[x]-1,y);
     95         }
     96         if (k==4){
     97             read(x);
     98             printf("%d
    ",query(1,dfn[x],dfn[x]+size[x]-1));
     99         }
    100     }
    101     return 0;
    102 }
    View Code
  • 相关阅读:
    移动开发 Native APP、Hybrid APP和Web APP介绍
    urllib与urllib2的学习总结(python2.7.X)
    fiddler及postman讲解
    接口测试基础
    UiAutomator2.0 和1.x 的区别
    adb shell am instrument 命令详解
    GT问题记录
    HDU 2492 Ping pong (树状数组)
    CF 567C Geometric Progression
    CF 545E Paths and Trees
  • 原文地址:https://www.cnblogs.com/DriverLao/p/7799721.html
Copyright © 2011-2022 走看看