zoukankan      html  css  js  c++  java
  • 【数据结构】——树链剖分

    树链剖分——简单而强大的数据维护方法

    只是放个板子而已。

    用我的码风覆盖了的。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 //------------------------------------------------------
      4 inline int read(){
      5     int f=1,x=0;
      6     char c=getchar();
      7     while(!isdigit(c)){
      8         if(c=='-') f=-1;
      9         c=getchar();
     10     } 
     11     while(isdigit(c)){
     12         x=x*10+c-'0';
     13         c=getchar();
     14     } 
     15     return x*f;
     16 }
     17 //------------------------------------------------------
     18 const int N=2e5+10;
     19 int at[N<<1],sum[N<<1];
     20 int head[N],cnt,n,m,r,mod,tot,ans;
     21 int w[N],dep[N],siz[N],fa[N],son[N],top[N],id[N],w2[N];
     22 struct edge{ int to,next; }e[N<<1];
     23 inline void addedge(int from,int to){ e[++cnt]=(edge){to,head[from]};head[from]=cnt; }
     24 inline void add(int x,int y){addedge(x,y),addedge(y,x);}
     25 //-------------------------------------------------------
     26 void dfs1(int u,int f){
     27     dep[u]=dep[f]+1;
     28     siz[u]=1;
     29     fa[u]=f;
     30     int maxson=0;
     31     for(int i=head[u];i;i=e[i].next){
     32         int v=e[i].to;
     33         if(v==f) continue;
     34         dfs1(v,u);
     35         siz[u]+=siz[v];
     36         if(siz[v]>maxson) maxson=siz[v],son[u]=v;
     37     }
     38 }
     39 void dfs2(int u,int f){
     40     id[u]=++tot;
     41     w2[tot]=w[u];
     42     top[u]=f;
     43     if(!son[u]) return;
     44     dfs2(son[u],f);
     45     for(int i=head[u];i;i=e[i].next){
     46         int v=e[i].to;
     47         if(v==fa[u]||v==son[u]) continue;
     48         dfs2(v,v);
     49     }
     50 }
     51 //-------------------------------------------------------
     52 class Tree{
     53     private:
     54         inline int ls(int o){return o<<1;}
     55         inline int rs(int o){return o<<1|1;}
     56         inline void pushdown(int o,int l,int r){
     57             if(!at[o]) return;
     58             int mid=(l+r)>>1;
     59             sum[ls(o)]=(sum[ls(o)]+at[o]*(mid-l+1))%mod;
     60             sum[rs(o)]=(sum[rs(o)]+at[o]*(r-mid))%mod;
     61             at[ls(o)]=(at[ls(o)]+at[o])%mod;
     62             at[rs(o)]=(at[rs(o)]+at[o])%mod;
     63             at[o]=0;
     64         }
     65         inline void pushup(int o){ sum[o]=(sum[ls(o)]+sum[rs(o)])%mod;}
     66     public:
     67         void build(int o,int l,int r){
     68             if(l==r){
     69                 sum[o]=w2[l];
     70                 if(sum[o]>mod) sum[o]%=mod;
     71                 return;
     72             }
     73             int mid=(l+r)>>1;
     74             build(ls(o),l,mid);
     75             build(rs(o),mid+1,r);
     76             pushup(o);
     77         }
     78         void change(int o,int l,int r,int x,int y,int k){
     79             if(l>y||r<x) return;
     80             if(x<=l&&r<=y){
     81                 sum[o]+=(r-l+1)*k;
     82                 at[o]+=k;
     83                 return;
     84             }
     85             int mid=(l+r)>>1;
     86             pushdown(o,l,r);
     87             if(x<=mid) change(ls(o),l,mid,x,y,k);
     88             if(y>mid) change(rs(o),mid+1,r,x,y,k);
     89             pushup(o);
     90         }
     91         void query(int o,int l,int r,int x,int y){
     92             if(l>y||r<x) return;
     93             if(x<=l&&r<=y){
     94                 ans+=sum[o];
     95                 ans%=mod;
     96                 return;
     97             }
     98             int mid=(l+r)>>1;
     99             pushdown(o,l,r);
    100             if(x<=mid) query(ls(o),l,mid,x,y);
    101             if(y>mid) query(rs(o),mid+1,r,x,y);
    102         }
    103         inline int ask(int u,int v){
    104             int cur=0;
    105             while(top[u]!=top[v]){
    106                 if(dep[top[u]]<dep[top[v]]) swap(u,v);
    107                 ans=0;
    108                 query(1,1,n,id[top[u]],id[u]);
    109                 cur+=ans;
    110                 cur%=mod;
    111                 u=fa[top[u]];
    112             }
    113             ans=0;
    114             if(dep[u]>dep[v]) swap(u,v);
    115             query(1,1,n,id[u],id[v]);
    116             cur+=ans;
    117             return cur%mod;
    118         }
    119         inline void ask2(int u,int v,int k){
    120             k%=mod;
    121             while(top[u]!=top[v]){
    122                 if(dep[top[u]]<dep[top[v]]) swap(u,v);
    123                 change(1,1,n,id[top[u]],id[u],k);
    124                 u=fa[top[u]];
    125             }
    126             if(dep[u]>dep[v]) swap(u,v);
    127             change(1,1,n,id[u],id[v],k);
    128         }    
    129 }T;
    130 //-------------------------------------------------------
    131 int main(){
    132     n=read();m=read();r=read();mod=read();
    133     int k,x,y,z;
    134     for(register int i=1;i<=n;i++) w[i]=read();
    135     for(register int i=1;i<n;i++) add(read(),read());
    136     dfs1(r,0);
    137     dfs2(r,r);
    138     T.build(1,1,n);
    139     for(register int i=1;i<=m;i++){
    140         k=read();
    141         if(k==1){
    142             x=read();y=read();z=read();
    143             T.ask2(x,y,z);
    144         }
    145         else if(k==2){
    146             x=read();y=read();
    147             printf("%d
    ",T.ask(x,y));
    148         }
    149         else if(k==3){
    150             x=read();z=read();
    151             T.change(1,1,n,id[x],id[x]+siz[x]-1,z);
    152         }
    153         else{
    154             x=read();ans=0;
    155             T.query(1,1,n,id[x],id[x]+siz[x]-1);
    156             printf("%d
    ",ans);
    157         }
    158     }
    159     return 0;
    160 } 
    ——抓住了时间,却不会利用的人,终究也逃不过失败的命运。
  • 相关阅读:
    【Git教程】Git教程之分支管理
    【Git教程】Git教程及使用命令
    【深入理解Java虚拟机】自动内存管理机制——垃圾回收机制
    HDU-5902-GCD is Funny解题笔记
    数据结构——二叉树的遍历
    数据结构——树
    Css--input输入框点击时去掉外框outline:medium;(chrome)
    JSON中eval与parse的区别
    【转载】实时监听输入框值变化的完美方案:oninput & onpropertychange
    使用寄存器点亮LED(第2节)—寄存器映射代码讲解
  • 原文地址:https://www.cnblogs.com/Nelson992770019/p/11826788.html
Copyright © 2011-2022 走看看