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

    洛谷:P3384 【模板】树链剖分

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<algorithm>
      4 #define ls (k*2)
      5 #define rs (k*2+1)
      6 #define down() {lz[ls]+=lz[k];lz[rs]+=lz[k];(sum[ls]+=(mid-ll+1)*lz[k])%=mod;(sum[rs]+=(rr-mid)*lz[k])%=mod;lz[k]=0;} //注意是ll和rr,不是L和R,又调了半天。。。
      7 using namespace std;
      8 const int MAXN=100099,MAXM=200099;
      9 int n,m,root,mod,num,DFN,op,x,y,z;
     10 int head[MAXN],from[MAXM],to[MAXM],Next[MAXM];
     11 int top[MAXN],w1[MAXN],w2[MAXN],fa[MAXN],son[MAXN],Val[MAXN],dep[MAXN],sz[MAXN],lz[MAXN*5],sum[MAXN*5];
     12 void add(int f,int t)
     13 {
     14   Next[++num]=head[f];
     15   to[num]=t;
     16   head[f]=num;
     17 }
     18 void dfs1(int u,int FA)
     19 {
     20   sz[u]=1;
     21   for(int i=head[u],v=to[i];i;i=Next[i],v=to[i])
     22     if(v!=FA)
     23       {
     24         dep[v]=dep[u]+1;
     25         fa[v]=u;
     26         dfs1(v,u);
     27         sz[u]+=sz[v];
     28         if(sz[v]>sz[son[u]]) son[u]=v;
     29       }
     30 }
     31 void dfs2(int u)
     32 {
     33   w1[u]=++DFN;
     34   if(son[u]!=0)
     35     {
     36       top[son[u]]=top[u];
     37       dfs2(son[u]);
     38     }
     39   for(int i=head[u],v=to[i];i;i=Next[i],v=to[i])
     40     if(v!=son[u] && !w1[v])
     41       {
     42         top[v]=v;
     43         dfs2(v);
     44       }
     45   w2[u]=DFN;
     46 }
     47 void Update(int k,int ll,int rr,int L,int R,int V)
     48 {
     49   if(ll==L && rr==R){sum[k]+=(R-L+1)*V%mod; sum[k]%=mod; lz[k]+=V; return;}
     50   int mid=(ll+rr)/2; down();
     51   if(R<=mid) Update(ls,ll,mid,L,R,V);
     52   else if(mid<L) Update(rs,mid+1,rr,L,R,V);
     53   else Update(ls,ll,mid,L,mid,V) , Update(rs,mid+1,rr,mid+1,R,V);
     54   sum[k]=(sum[ls]+sum[rs])%mod;
     55 }
     56 int Query(int k,int ll,int rr,int L,int R)
     57 {
     58   if(ll==L && rr==R){return sum[k];}
     59   int mid=(ll+rr)/2; down();
     60   if(R<=mid) return Query(ls,ll,mid,L,R);
     61   else if(mid<L) return Query(rs,mid+1,rr,L,R);
     62   else return (Query(ls,ll,mid,L,mid)+Query(rs,mid+1,rr,mid+1,R))%mod;
     63 }
     64 int main()
     65 {
     66   scanf("%d%d%d%d",&n,&m,&root,&mod);
     67   for(int i=1;i<=n;i++) scanf("%d",&Val[i]);
     68   for(int i=1,a,b;i<n;i++)
     69     {
     70       scanf("%d%d",&a,&b);
     71       add(a,b); add(b,a);
     72     }
     73   top[root]=root;
     74   dep[root]=1;
     75   dfs1(root,0);
     76   dfs2(root);
     77   for(int i=1;i<=n;i++) Update(1,1,n,w1[i],w1[i],Val[i]%mod);
     78   while(m--)
     79     {
     80       scanf("%d",&op);
     81       if(op==1)
     82         {
     83           scanf("%d%d%d",&x,&y,&z); z%=mod;
     84           while(top[x]!=top[y])
     85             {
     86               if(dep[top[x]]<dep[top[y]]) swap(x,y);
     87               Update(1,1,n,w1[top[x]],w1[x],z);
     88               x=fa[top[x]];
     89             }
     90           if(dep[x]<dep[y]) swap(x,y);
     91           Update(1,1,n,w1[y],w1[x],z);
     92         }
     93       else if(op==2)
     94         {
     95           scanf("%d%d",&x,&y);
     96           int ans=0;
     97           while(top[x]!=top[y])
     98             {
     99               if(dep[top[x]]<dep[top[y]]) swap(x,y);
    100               (ans+=Query(1,1,n,w1[top[x]],w1[x]))%=mod;
    101               x=fa[top[x]];
    102             }
    103           if(dep[x]<dep[y]) swap(x,y);
    104           (ans+=Query(1,1,n,w1[y],w1[x]))%=mod;
    105           printf("%d
    ",ans%mod);
    106         }
    107       else if(op==3)
    108         {
    109           scanf("%d%d",&x,&z); z%=mod;
    110           Update(1,1,n,w1[x],w2[x],z);
    111         }
    112       else if(op==4)
    113         {
    114           scanf("%d",&x);
    115           printf("%d
    ",Query(1,1,n,w1[x],w2[x]));
    116         }
    117     }
    118   return 0;
    119 }
  • 相关阅读:
    创建型设计模式-原型模式(单例) MemberwiseClone()
    Oracle 查看没有释放的链接 和删除,相关sql
    win10 安装 SQL Developer 工具
    修改nuget包默认存放路径 win10
    使用端口查询
    未能加载文件或程序集“Newtonsoft.Json, Version=12.0.0.0,
    微信错误码
    sqlserver 时间转换记录
    Homebrew 使用指南
    在Mac检查安装的.net core 版本
  • 原文地址:https://www.cnblogs.com/D-O-Time/p/8040112.html
Copyright © 2011-2022 走看看