zoukankan      html  css  js  c++  java
  • 重链剖分模板

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define maxn 100010
      6 
      7 using namespace std;
      8 
      9 struct node
     10 {
     11     int ed,nxt;
     12 };
     13 node edge[maxn<<1];
     14 int n,m,root,cnt,first[maxn],p;
     15 int fa[maxn],siz[maxn],son[maxn],dep[maxn];
     16 int rnk[maxn],seg[maxn],top[maxn],rnk_cnt;
     17 int num[maxn],num_rnk[maxn],tree[maxn<<2],tag[maxn<<2],ans,tot;
     18 
     19 inline void add_edge(int s,int e)
     20 {
     21     ++cnt;
     22     edge[cnt].ed=e;
     23     edge[cnt].nxt=first[s];
     24     first[s]=cnt;
     25     return;
     26 }
     27 
     28 inline void dfs_1(int now,int pre)
     29 {
     30     dep[now]=dep[pre]+1; fa[now]=pre; siz[now]=1;
     31     for(register int i=first[now];i;i=edge[i].nxt)
     32     {
     33         int e=edge[i].ed;
     34         if(e==pre) continue;
     35         dfs_1(e,now);
     36         siz[now]+=siz[e];
     37         if(son[now]==-1||siz[e]>siz[son[now]]) son[now]=e;
     38     }
     39     return;
     40 }
     41 
     42 inline void dfs_2(int now,int heavy_fa)
     43 {
     44     ++rnk_cnt;
     45     rnk[now]=rnk_cnt; seg[rnk_cnt]=now; top[now]=heavy_fa;num_rnk[rnk_cnt]=num[now];
     46     if(son[now]==-1) return;
     47     dfs_2(son[now],heavy_fa);
     48     for(register int i=first[now];i;i=edge[i].nxt)
     49     {
     50         int e=edge[i].ed;
     51         if(e!=fa[now]&&e!=son[now]) dfs_2(e,e);
     52     }
     53     return;
     54 }
     55 
     56 inline void build(int k,int l,int r)
     57 {
     58     if(l==r)
     59     {
     60         tree[k]=num_rnk[l]%p;
     61         return;
     62     }
     63     int mid=(l+r)>>1,son=k<<1;
     64     build(son,l,mid); build(son|1,mid+1,r);
     65     tree[k]=(tree[son]+tree[son|1])%p;
     66     return;
     67 }
     68 
     69 inline void push_down(int k,int l,int r)
     70 {
     71     int mid=(l+r)>>1,son=k<<1;
     72     tree[son]=(tree[son]+(mid-l+1)*tag[k])%p; tag[son]=(tag[son]+tag[k])%p;
     73     tree[son|1]=(tree[son|1]+(r-mid)*tag[k])%p; tag[son|1]=(tag[son|1]+tag[k])%p;
     74     tag[k]=0;
     75     return;
     76 }
     77 
     78 inline void modify(int k,int l,int r,int x,int y,int v)
     79 {
     80     if(r<x||l>y) return;
     81     if(x<=l&&r<=y)
     82     {
     83         tree[k]=(tree[k]+v*(r-l+1))%p;
     84         tag[k]=(tag[k]+v)%p;
     85         return;
     86     }
     87     if(tag[k]) push_down(k,l,r);
     88     int mid=(l+r)>>1,son=k<<1;
     89     modify(son,l,mid,x,y,v); modify(son|1,mid+1,r,x,y,v);
     90     tree[k]=(tree[son]+tree[son|1])%p;
     91     return;
     92 }
     93 
     94 
     95 inline void modify_tree(int x,int y,int v)
     96 {
     97     while(top[x]!=top[y])
     98     {
     99         if(dep[top[x]]<dep[top[y]]) swap(x,y);
    100         modify(1,1,n,rnk[top[x]],rnk[x],v);
    101         x=fa[top[x]];
    102     }
    103     modify(1,1,n,min(rnk[x],rnk[y]),max(rnk[x],rnk[y]),v);
    104     return;
    105 }
    106 
    107 inline void get_sum(int k,int l,int r,int x,int y)
    108 {
    109     if(r<x||l>y) return;
    110     if(x<=l&&r<=y)
    111     {
    112         tot=(tot+tree[k])%p;
    113         return;
    114     }
    115     if(tag[k]) push_down(k,l,r);
    116     int mid=(l+r)>>1,son=k<<1;
    117     get_sum(son,l,mid,x,y); get_sum(son|1,mid+1,r,x,y);
    118     tree[k]=(tree[son]+tree[son|1])%p;
    119     return;
    120 }
    121 
    122 inline void tree_sum(int x,int y)
    123 {
    124     while(top[x]!=top[y])
    125     {
    126         if(dep[top[x]]<dep[top[y]]) swap(x,y);
    127         tot=0;
    128         get_sum(1,1,n,rnk[top[x]],rnk[x]);
    129         ans=(ans+tot)%p;
    130         x=fa[top[x]];
    131     }
    132     tot=0;
    133     get_sum(1,1,n,min(rnk[x],rnk[y]),max(rnk[x],rnk[y]));
    134     ans=(ans+tot)%p;
    135     return;
    136 }
    137 
    138 int main()
    139 {
    140     scanf("%d%d%d%d",&n,&m,&root,&p);
    141     for(register int i=1;i<=n;++i)
    142         scanf("%d",&num[i]);
    143     for(register int i=1;i<=n-1;++i)
    144     {
    145         int s,e;
    146         scanf("%d%d",&s,&e);
    147         add_edge(s,e);
    148         add_edge(e,s);
    149     }
    150     memset(son,-1,sizeof(son));
    151     dfs_1(root,0);
    152     dfs_2(root,root);
    153     build(1,1,n);
    154     for(register int i=1;i<=m;++i)
    155     {
    156         int opt;
    157         scanf("%d",&opt);
    158         if(opt==1)
    159         {
    160             int x,y,v;
    161             scanf("%d%d%d",&x,&y,&v);
    162             modify_tree(x,y,v%p);
    163         }
    164         else if(opt==2)
    165         {
    166             int x,y;
    167             ans=0;
    168             scanf("%d%d",&x,&y);
    169             tree_sum(x,y);
    170             printf("%d
    ",ans%p); 
    171         }
    172         else if (opt==3)
    173         {
    174             int x,v;
    175             scanf("%d%d",&x,&v);
    176             modify(1,1,n,rnk[x],rnk[x]+siz[x]-1,v%p);
    177         }
    178         else if(opt==4)
    179         {
    180             int x;
    181             scanf("%d",&x);
    182             tot=0;
    183             //printf("%d %d
    ",rnk[x],rnk[x]+siz[x]-1);
    184             get_sum(1,1,n,rnk[x],rnk[x]+siz[x]-1);
    185             printf("%d
    ",tot%p);
    186         }
    187     }
    188     return 0;
    189 } 

    Orz

  • 相关阅读:
    IE无法引入css文件
    各个浏览器的兼容性及解决方法小结
    position的用法小结
    vertical-align的理解
    月薪5K和月薪10K,是能力问题还是公司问题?
    程序员如何在QQ群、微信群里装逼?
    一个计算机专业毕业生工作 5 年后的困惑
    CTO 比普通程序员强在哪?
    干程序员辣么久,你为什么还没有年薪60万?
    做一个App究竟要花多少钱?
  • 原文地址:https://www.cnblogs.com/Hoyoak/p/11813241.html
Copyright © 2011-2022 走看看