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

    树链剖分

    (不就是两个dfs吗干嘛起这么高大上的名字)

      1 //hdu3966
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<cmath>
      7 #pragma comment(linker, "/STACK:1024000000,1024000000")
      8 using namespace std;
      9 struct edge{
     10     int v,next;
     11 }a[2000001];
     12 int n,m,q,u,v,ww,now=0,tot=0,sum[2000001],cal[2000001],num[200001],head[200001],son[200001],siz[200001],dep[200001],fa[200001],top[200001],vis[200001],w[200001];
     13 char ord[10];
     14 int max(int a,int b){
     15     return a>b?a:b;
     16 }
     17 void add(int u,int v){
     18     a[++tot].v=v;
     19     a[tot].next=head[u];
     20     head[u]=tot;
     21 }
     22 void dfs1(int u,int f,int dp){
     23     int v;
     24     dep[u]=dp;
     25     fa[u]=f;
     26     siz[u]=1;
     27     for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
     28         v=a[tmp].v;
     29         if(v!=f){
     30             dfs1(v,u,dp+1);
     31             siz[u]+=siz[v];
     32             if(son[u]==-1||siz[v]>siz[son[u]]){
     33                 son[u]=v;
     34             }
     35         }
     36     }
     37 }
     38 void dfs2(int u,int tp){
     39     int v;
     40     top[u]=tp;
     41     vis[u]=++now;
     42     w[vis[u]]=u;
     43     if(son[u]==-1)return;
     44     dfs2(son[u],tp);
     45     for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
     46         v=a[tmp].v;
     47         if(v!=son[u]&&v!=fa[u])dfs2(v,v);
     48     }
     49 }
     50 void pushD(int rt,int len){
     51     if(cal[rt]){
     52         cal[rt<<1]+=cal[rt];
     53         cal[rt<<1|1]+=cal[rt];
     54         sum[rt<<1]+=(len-len/2)*cal[rt];
     55         sum[rt<<1|1]+=(len/2)*cal[rt];
     56         cal[rt]=0;
     57     }
     58 }
     59 void build(int l,int r,int rt){
     60     cal[rt]=0;
     61     if(l==r){
     62         sum[rt]=num[w[l]];
     63         return;
     64     }
     65     int mid=(l+r)/2;
     66     build(l,mid,rt<<1);
     67     build(mid+1,r,rt<<1|1);
     68     sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
     69 }
     70 void updata(int rt,int k,int l,int r,int L,int R){
     71     if(L<=l&&r<=R){
     72         cal[rt]+=k;
     73         sum[rt]+=k*(r-l+1);
     74         return;
     75     }
     76     int mid=(l+r)/2;
     77     pushD(rt,r-l+1);
     78     if(L<=mid)updata(rt<<1,k,l,mid,L,R);
     79     if(R>mid)updata(rt<<1|1,k,mid+1,r,L,R);
     80     sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
     81 }
     82 int query(int rt,int l,int r,int aa){
     83     if(l==r){
     84         return sum[rt];
     85     }
     86     int ans=0,mid=(l+r)/2;
     87     pushD(rt,r-l+1);
     88     if(aa<=mid)ans=query(rt<<1,l,mid,aa);
     89     else ans=query(rt<<1|1,mid+1,r,aa);
     90     sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
     91     return ans;
     92 }
     93 void update(int u,int v,int w){
     94     while(top[u]!=top[v]){
     95         if(dep[top[u]]<dep[top[v]])swap(u,v);
     96         updata(1,w,1,n,vis[top[u]],vis[u]);
     97         u=fa[top[u]];
     98     }
     99     if(dep[u]>dep[v])swap(u,v);
    100     updata(1,w,1,n,vis[u],vis[v]);
    101 }
    102 int main(){
    103     while(scanf("%d%d%d",&n,&m,&q)!=EOF){
    104         memset(head,255,sizeof(head));
    105         memset(son,255,sizeof(son));
    106         tot=now=0;
    107         for(int i=1;i<=n;i++){
    108             scanf("%d",&num[i]);
    109         }
    110         for(int i=1;i<=m;i++){
    111             scanf("%d%d",&u,&v);
    112             add(u,v);
    113             add(v,u);
    114         }
    115         dfs1(1,0,0);
    116         dfs2(1,1);
    117         build(1,n,1);
    118         for(int i=1;i<=q;i++){
    119             scanf("%s",ord);
    120             if(ord[0]=='Q'){
    121                 scanf("%d",&u);
    122                 printf("%d
    ",query(1,1,n,vis[u]));
    123             }else{
    124                 scanf("%d%d%d",&u,&v,&ww);
    125                 if(ord[0]=='D')ww=-ww;
    126                 update(u,v,ww);
    127             }
    128         }
    129     }
    130     return 0;
    131 }
    132 /*
    133 3 2 5
    134 1 2 3
    135 2 1
    136 2 3
    137 I 1 3 5
    138 Q 2
    139 D 1 2 2
    140 Q 1 
    141 Q 3
    142 --------
    143 7
    144 4
    145 8
    146 */
  • 相关阅读:
    ASP.NET HTTP404错误怎么办
    ASP.NET HTTP500错误怎么办
    Fireworks如何制作透明窗口PNG
    CSS如何实现自定义鼠标应用到整个网页
    Dreamweaver如何设置自动换行,修改字体
    火狐浏览器缓存区的利用,如何提取火狐缓存的动画
    PHP快速入门 如何配置Apache服务器
    PHP中调用外部命令的方法
    PHP与SQL数据库交互中文乱码怎么办
    [Angular] Angular Attribute Decorator
  • 原文地址:https://www.cnblogs.com/dcdcbigbig/p/8945157.html
Copyright © 2011-2022 走看看