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

    模板

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<string>
      5 #include<cmath>
      6 using namespace std;
      7 inline int read()
      8 {
      9     char ch=getchar();
     10     int a=0,t=1;
     11     while(ch<'0'||ch>'9') {if(ch=='-') t=-1;ch=getchar();}
     12     while(ch<='9'&&ch>='0') {a=a*10+ch-'0';ch=getchar();}
     13     return a*t;
     14 }
     15 inline long long readll()
     16 {
     17     char ch=getchar();
     18     long long a=0,t=1;
     19     while(ch<'0'||ch>'9') {if(ch=='-') t=-1;ch=getchar();}
     20     while(ch<='9'&&ch>='0') {a=a*10+ch-'0';ch=getchar();}
     21     return a*t;
     22 }
     23 inline void write(int k){
     24     if (k<0) {
     25         putchar('-');
     26         k=-k;
     27     }
     28     if (k>9) write(k/10);
     29     putchar(k%10+'0');
     30 }
     31 int n,m,r,num=0;
     32 long long p;
     33 int father[500005],dep[500005]={0},son_num[500005];
     34 int heavy_son[500005],id[500005],real[500005];
     35 long long top[500005];
     36 struct tree_arr{
     37     long long sum,tag,l,r;
     38 }tree[500005];
     39 int head[500005],a[500005];
     40 struct edge_arr{
     41     int to,next;
     42 }edge[500005];
     43 inline void lianshi(int u,int v){
     44     num++; edge[num].to=v; edge[num].next=head[u]; head[u]=num;
     45 }
     46 inline void dfs1(int now,int fa){
     47     father[now]=fa; 
     48     dep[now]=dep[father[now]]+1;
     49     son_num[now]=1;
     50     for (int i=head[now];i!=-1;i=edge[i].next){
     51         if (edge[i].to!=father[now]){
     52             dfs1(edge[i].to,now);
     53             son_num[now]+=son_num[edge[i].to];
     54             if (heavy_son[now]<=0 || son_num[heavy_son[now]]<son_num[edge[i].to]){
     55                 heavy_son[now]=edge[i].to;
     56             }
     57         }
     58     }
     59 }
     60 int temp=0;
     61 inline void dfs2(int now,int root){
     62     top[now]=root;
     63     temp++; 
     64     id[now]=temp; 
     65     //printf("%d %d
    ",now,id[now]);
     66     real[id[now]]=now;
     67     if (heavy_son[now]<=0) return;
     68     dfs2(heavy_son[now],root);
     69     for (int i=head[now];i!=-1;i=edge[i].next){
     70         if (edge[i].to!=father[now] && edge[i].to!=heavy_son[now]){
     71             dfs2(edge[i].to,edge[i].to);
     72         }
     73     }
     74 }
     75 inline void buildtree(int root,int l,int r){
     76     tree[root].l=l; tree[root].r=r;
     77     if (l==r){
     78         tree[root].sum=a[real[l]]; return;
     79     }
     80     int mid=(l+r)>>1;
     81     buildtree(root*2,l,mid); 
     82     buildtree(root*2+1,mid+1,r);
     83     tree[root].sum=tree[root*2].sum+tree[root*2+1].sum;
     84 }
     85 inline void push_down(int root){
     86     tree[root*2].tag+=tree[root].tag; 
     87     tree[root*2].sum+=tree[root].tag*(tree[root*2].r-tree[root*2].l+1);
     88     tree[root*2+1].tag+=tree[root].tag; 
     89     tree[root*2+1].sum+=tree[root].tag*(tree[root*2+1].r-tree[root*2+1].l+1);
     90     tree[root].tag=0;
     91 }
     92 inline void addall(int root,int l,int r,long long x){
     93     if (l>tree[root].r || r<tree[root].l) return;
     94     if (l<=tree[root].l && r>=tree[root].r){
     95         tree[root].tag+=x; tree[root].sum+=x*(tree[root].r-tree[root].l+1);
     96         return;
     97     }
     98     push_down(root);
     99     int mid=(tree[root].l+tree[root].r)>>1;
    100     if (r<=mid) addall(root*2,l,r,x);
    101     else if (l>mid) addall(root*2+1,l,r,x);
    102          else addall(root*2,l,mid,x),addall(root*2+1,mid+1,r,x);
    103     tree[root].sum=tree[root*2].sum+tree[root*2+1].sum;
    104 }
    105 inline void change(int u,int v,long long x){
    106     int zuxian_u=top[u],zuxian_v=top[v];
    107     while (zuxian_u!=zuxian_v){
    108         if (dep[zuxian_u]<dep[zuxian_v]){
    109             swap(u,v); swap(zuxian_u,zuxian_v);
    110         }
    111         addall(1,id[zuxian_u],id[u],x);
    112         u=father[zuxian_u]; zuxian_u=top[u];
    113     }
    114     if (dep[u]>dep[v]){
    115         swap(u,v);
    116     }
    117     addall(1,id[u],id[v],x);
    118 }
    119 inline long long findsum(int root,int l,int r){
    120     if (l>tree[root].r || r<tree[root].l) return 0;
    121     if (l<=tree[root].l && r>=tree[root].r){
    122         return tree[root].sum;
    123     }
    124     push_down(root);
    125     int mid=(tree[root].l+tree[root].r)>>1;
    126     if (r<=mid) return findsum(root*2,l,r);
    127     else if (l>mid) return findsum(root*2+1,l,r);
    128          else return findsum(root*2,l,mid)+findsum(root*2+1,mid+1,r);
    129 }
    130 inline long long findans(int u,int v){
    131     long long sum=0; int zuxian_u=top[u],zuxian_v=top[v];
    132     while (zuxian_u!=zuxian_v){
    133         if (dep[zuxian_u]<dep[zuxian_v]){
    134             swap(u,v); swap(zuxian_u,zuxian_v);
    135         }
    136         sum+=findsum(1,id[zuxian_u],id[u]);        
    137         sum%=p; 
    138         u=father[zuxian_u];
    139         zuxian_u=top[u];
    140     }
    141     if (dep[u]>dep[v]){
    142         swap(u,v);
    143     }
    144     sum+=findsum(1,id[u],id[v]);
    145     sum%=p;
    146     return sum;
    147 }
    148 int main(){
    149     n=read(),m=read(),r=read(),p=readll();
    150     for (int i=1;i<=n;i++) a[i]=read(),head[i]=-1;
    151     for (int i=1;i<n;i++){
    152         int u=read(),v=read(); lianshi(u,v); lianshi(v,u);
    153     } 
    154     dep[0]=0; son_num[0]=-1;
    155     dfs1(r,0); 
    156     dfs2(r,r);
    157     /*for (int i=1;i<=n;i++){
    158         printf("%d %d %d %d %d %d %d
    ",i,father[i],dep[i],son_num[i],heavy_son[i],top[i],id[i]);
    159     }
    160     return 0;*/
    161     
    162     buildtree(1,1,temp);
    163     
    164     for (int i=1;i<=m;i++){
    165         int k=read();
    166         if (k==1){
    167             int x=read(),y=read(),z=readll(); change(x,y,z);
    168         }
    169         if (k==2){
    170             int x=read(),y=read(); printf("%lld
    ",findans(x,y)%p);
    171         }
    172         if (k==3){
    173             int x=read(),y=readll(); addall(1,id[x],id[x]+son_num[x]-1,y);
    174         }
    175         if (k==4){
    176             int x=read(); printf("%lld
    ",findsum(1,id[x],id[x]+son_num[x]-1)%p);
    177         }
    178     }
    179     return 0;
    180 }

    #include<iostream>#include<cstdio>#include<cstring>#include<string>#include<cmath>using namespace std;inline int read(){    char ch=getchar();    int a=0,t=1;    while(ch<'0'||ch>'9') {if(ch=='-') t=-1;ch=getchar();}    while(ch<='9'&&ch>='0') {a=a*10+ch-'0';ch=getchar();}    return a*t;}inline long long readll(){    char ch=getchar();    long long a=0,t=1;    while(ch<'0'||ch>'9') {if(ch=='-') t=-1;ch=getchar();}    while(ch<='9'&&ch>='0') {a=a*10+ch-'0';ch=getchar();}    return a*t;}inline void write(int k){if (k<0) {putchar('-');k=-k;}if (k>9) write(k/10);putchar(k%10+'0');}int n,m,r,num=0;long long p;int father[500005],dep[500005]={0},son_num[500005];int heavy_son[500005],id[500005],real[500005];long long top[500005];struct tree_arr{long long sum,tag,l,r;}tree[500005];int head[500005],a[500005];struct edge_arr{int to,next;}edge[500005];inline void lianshi(int u,int v){num++; edge[num].to=v; edge[num].next=head[u]; head[u]=num;}inline void dfs1(int now,int fa){father[now]=fa; dep[now]=dep[father[now]]+1;son_num[now]=1;for (int i=head[now];i!=-1;i=edge[i].next){if (edge[i].to!=father[now]){dfs1(edge[i].to,now);son_num[now]+=son_num[edge[i].to];if (heavy_son[now]<=0 || son_num[heavy_son[now]]<son_num[edge[i].to]){heavy_son[now]=edge[i].to;}}}}int temp=0;inline void dfs2(int now,int root){top[now]=root;temp++; id[now]=temp; //printf("%d %d ",now,id[now]);real[id[now]]=now;if (heavy_son[now]<=0) return;dfs2(heavy_son[now],root);for (int i=head[now];i!=-1;i=edge[i].next){if (edge[i].to!=father[now] && edge[i].to!=heavy_son[now]){dfs2(edge[i].to,edge[i].to);}}}inline void buildtree(int root,int l,int r){tree[root].l=l; tree[root].r=r;if (l==r){tree[root].sum=a[real[l]]; return;}int mid=(l+r)>>1;buildtree(root*2,l,mid); buildtree(root*2+1,mid+1,r);tree[root].sum=tree[root*2].sum+tree[root*2+1].sum;}inline void push_down(int root){tree[root*2].tag+=tree[root].tag; tree[root*2].sum+=tree[root].tag*(tree[root*2].r-tree[root*2].l+1);tree[root*2+1].tag+=tree[root].tag; tree[root*2+1].sum+=tree[root].tag*(tree[root*2+1].r-tree[root*2+1].l+1);tree[root].tag=0;}inline void addall(int root,int l,int r,long long x){if (l>tree[root].r || r<tree[root].l) return;if (l<=tree[root].l && r>=tree[root].r){tree[root].tag+=x; tree[root].sum+=x*(tree[root].r-tree[root].l+1);return;}push_down(root);int mid=(tree[root].l+tree[root].r)>>1;if (r<=mid) addall(root*2,l,r,x);else if (l>mid) addall(root*2+1,l,r,x);     else addall(root*2,l,mid,x),addall(root*2+1,mid+1,r,x);tree[root].sum=tree[root*2].sum+tree[root*2+1].sum;}inline void change(int u,int v,long long x){int zuxian_u=top[u],zuxian_v=top[v];while (zuxian_u!=zuxian_v){if (dep[zuxian_u]<dep[zuxian_v]){swap(u,v); swap(zuxian_u,zuxian_v);}addall(1,id[zuxian_u],id[u],x);u=father[zuxian_u]; zuxian_u=top[u];}if (dep[u]>dep[v]){swap(u,v);}addall(1,id[u],id[v],x);}inline long long findsum(int root,int l,int r){if (l>tree[root].r || r<tree[root].l) return 0;if (l<=tree[root].l && r>=tree[root].r){return tree[root].sum;}push_down(root);int mid=(tree[root].l+tree[root].r)>>1;if (r<=mid) return findsum(root*2,l,r);else if (l>mid) return findsum(root*2+1,l,r);     else return findsum(root*2,l,mid)+findsum(root*2+1,mid+1,r);}inline long long findans(int u,int v){long long sum=0; int zuxian_u=top[u],zuxian_v=top[v];while (zuxian_u!=zuxian_v){if (dep[zuxian_u]<dep[zuxian_v]){swap(u,v); swap(zuxian_u,zuxian_v);}sum+=findsum(1,id[zuxian_u],id[u]);sum%=p; u=father[zuxian_u];zuxian_u=top[u];}if (dep[u]>dep[v]){swap(u,v);}sum+=findsum(1,id[u],id[v]);sum%=p;return sum;}int main(){    n=read(),m=read(),r=read(),p=readll();for (int i=1;i<=n;i++) a[i]=read(),head[i]=-1;for (int i=1;i<n;i++){int u=read(),v=read(); lianshi(u,v); lianshi(v,u);} dep[0]=0; son_num[0]=-1;dfs1(r,0); dfs2(r,r);/*for (int i=1;i<=n;i++){printf("%d %d %d %d %d %d %d ",i,father[i],dep[i],son_num[i],heavy_son[i],top[i],id[i]);}return 0;*/buildtree(1,1,temp);for (int i=1;i<=m;i++){int k=read();if (k==1){int x=read(),y=read(),z=readll(); change(x,y,z);}if (k==2){int x=read(),y=read(); printf("%lld ",findans(x,y)%p);}if (k==3){int x=read(),y=readll(); addall(1,id[x],id[x]+son_num[x]-1,y);}if (k==4){int x=read(); printf("%lld ",findsum(1,id[x],id[x]+son_num[x]-1)%p);}}return 0;}

  • 相关阅读:
    MongoDB入门
    MongoDB基础命令
    MongoDB查询
    MongoDB索引
    MongoDB聚合
    MongoDB进阶
    Elasticsearch简介与安装
    ElasticSearch索引
    shiro xml标准配置
    shiro双realm验证
  • 原文地址:https://www.cnblogs.com/lztlztlzt/p/7697710.html
Copyright © 2011-2022 走看看