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

    update: 2018-01-27

    下面的应该是很久之前抄的代码了,,当时应该是费了很大劲弄明白了一点吧=_=||

    最近一直再刷数据结构,今天终于刷到树链剖分了,看了一下代码感觉挺清晰的...

    具体讲解就看高级数据结构这本书吧,p401,感觉写的很清晰易懂。

    最近几天最大的感受就是,半年前怎么都搞不明白的东西现在可以轻轻松松看懂了。我想可能就是当时这些东西确实超出了我的理解能力吧,其实后来这半年感觉并没有什么进步,应该就是不知不觉中提升了吧,忽然想起来半年前去看一年前的东西也是一样的感觉。

    集训不剩几天了,之后还有别的事情要做呢,加油吧~



    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3966

    参考:http://blog.csdn.net/acdreamers/article/details/10594121

    明天再补代码,,睡觉!!

    ----------------------------------------------------------------------------------

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<iostream>
      5 using namespace std;
      6 const int maxn=50010;
      7 
      8 struct edge
      9 {
     10     int v,nex;
     11 }e[maxn<<1];
     12 
     13 int n,m,q;
     14 int cur;
     15 int w[maxn],siz[maxn],top[maxn],son[maxn];
     16  // 节点权重  子树节点数   链首        重儿子  
     17 int dep[maxn],f[maxn],order[maxn],tid[maxn];
     18  // 深度        父亲    生成线段     遍历序列编号   
     19 
     20 int head[maxn];
     21 int cnt;
     22 
     23 void init()
     24 {
     25     memset(head,-1,sizeof(head));
     26     memset(son,-1,sizeof(son));
     27     cur=0;
     28     cnt=0;
     29 }
     30 
     31 void adde(int u,int v)
     32 {
     33     e[cnt].v=v;
     34     e[cnt].nex=head[u];
     35     head[u]=cnt++;
     36 }
     37 
     38 
     39 
     40 //树链剖分
     41 void dfs1(int u,int fa,int d)
     42 {
     43     dep[u]=d;
     44     f[u]=fa;
     45     siz[u]=1;
     46     for(int i=head[u];i!=-1;i=e[i].nex)
     47     {
     48         int v=e[i].v;
     49         if(v!=fa)
     50         {
     51             dfs1(v,u,d+1);
     52             siz[u]+=siz[v];
     53             if(son[u]==-1||siz[v]>siz[son[u]])  //更新重儿子
     54                 son[u]=v;
     55         }
     56     }
     57 }
     58 
     59 void dfs2(int u,int tp)
     60 {
     61     top[u]=tp;
     62     tid[u]=++cur;
     63     order[tid[u]]=u;
     64     if(son[u]==-1) return ;
     65     dfs2(son[u],tp);
     66     for(int i=head[u];i!=-1;i=e[i].nex)
     67     {
     68         int v=e[i].v;
     69         if(v!=son[u]&&v!=f[u])
     70             dfs2(v,v);
     71     }
     72 }
     73 
     74 //线段树
     75 #define lson l,m,rt<<1
     76 #define rson m+1,r,rt<<1|1
     77 
     78 int sum[maxn<<2];
     79 int add[maxn<<2];
     80 
     81 void pushup(int rt)
     82 {
     83     sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
     84 }
     85 
     86 void pushdown(int rt,int m)
     87 {
     88     if(add[rt])
     89     {
     90         add[rt<<1]+=add[rt];
     91         add[rt<<1|1]+=add[rt];
     92         sum[rt<<1]+=add[rt]*(m-(m>>1));
     93         sum[rt<<1|1]+=add[rt]*(m>>1);
     94         add[rt]=0;
     95     }
     96 }
     97 
     98 void build(int l,int r,int rt)
     99 {
    100     add[rt]=0;
    101     if(l==r)
    102     {
    103         sum[rt]=w[order[l]];
    104         return ;
    105     }
    106     int m=(l+r)>>1;
    107     build(lson);
    108     build(rson);
    109     pushup(rt);
    110 }
    111 void update(int L,int R,int c,int l,int r,int rt)
    112 {
    113     if(L<=l&&r<=R)
    114     {
    115         add[rt]+=c;
    116         sum[rt]+=c*(r-l+1);
    117         return ;
    118     }
    119     pushdown(rt,r-l+1);
    120     int m=(l+r)>>1;
    121     if(L<=m) update(L,R,c,lson);
    122     if(R>m) update(L,R,c,rson);
    123     pushup(rt);
    124 }
    125 int query(int pos,int l,int r,int rt)
    126 {
    127     if(l==r) return sum[rt];
    128     pushdown(rt,r-l+1);
    129     int m=(l+r)>>1;
    130     int ans=0;
    131     if(pos<=m) ans=query(pos,lson);
    132     else ans=query(pos,rson);
    133     pushup(rt);
    134     return ans;
    135 }
    136 
    137 void change(int x,int y,int c)
    138 {
    139     while(top[x]!=top[y])  //不在一条链
    140     {
    141         if(dep[top[x]]<dep[top[y]]) swap(x,y);  
    142         update(tid[top[x]],tid[x],c,1,n,1);   // 更新链首深度大的那一条链
    143         x=f[top[x]];  // x所在链已更新完,将x记为x与y连接的那个点
    144     }
    145     if(dep[x]>dep[y]) swap(x,y);
    146     update(tid[x],tid[y],c,1,n,1);
    147 }
    148 
    149 int main()
    150 {
    151     char op[3];
    152     int a,b,c;
    153     int u,v;
    154     while(scanf("%d%d%d",&n,&m,&q)!=EOF)
    155     {
    156         init();
    157         for(int i=1;i<=n;i++)
    158             scanf("%d",&w[i]);
    159         for(int i=1;i<=m;i++)
    160         {
    161             scanf("%d%d",&u,&v);
    162             adde(u,v);
    163             adde(v,u);
    164         }
    165         dfs1(1,0,0);
    166         dfs2(1,1);
    167         build(1,n,1);
    168         while(q--)
    169         {
    170             scanf("%s",op);
    171             if(op[0]=='Q')
    172             {
    173                 scanf("%d",&a);
    174                 printf("%d
    ",query(tid[a],1,n,1));
    175             }
    176             else
    177             {
    178                 scanf("%d%d%d",&a,&b,&c);
    179                 if(op[0]=='D') c=-c;
    180                 change(a,b,c);
    181             }
    182         }
    183     }
    184     return 0;
    185 }
  • 相关阅读:
    NPM 与 left-pad 事件:我们是不是早已忘记该如何好好地编程?
    Groovy split竖杆注意
    使用Flask-Migrate进行管理数据库升级
    Fabric自动部署太方便了
    程序员的复仇:11行代码如何让Node.js社区鸡飞狗跳
    grails 私有库相关设置
    A successful Git branching model
    String to Date 多种格式转换
    C#搭建CEF(CEFGLUE) 环境。
    使用Win PE修改其他硬盘中的系统注册表
  • 原文地址:https://www.cnblogs.com/yijiull/p/6697140.html
Copyright © 2011-2022 走看看