• HDU 3966 Aragorn's Story 树链剖分+线段树


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

    题意:给出一棵树,规定有三种操作:I操作,C1到C2路径上点的权值增加K

                     D操作,C1到C2路径上点的权值减少K

                     Q操作,查询C点的权值

    思路:第一次练的树链剖分,套模板用线段树维护即可。

    代码:

      1 #include <iostream>
      2 #include <string.h>
      3 #include <algorithm>
      4 #include <stdio.h>
      5 #include <vector>
      6 
      7 using namespace std;
      8 //typedef long long ll;
      9 const int MAX=50009;
     10 
     11 int n,m,p,edge,x1,y1,z1,tim;
     12 
     13 struct tr
     14 {
     15     int l,r;
     16     int sum;
     17     int lazy;
     18 }tree[4*MAX];
     19 
     20 int a[MAX];
     21 int to[2*MAX],next1[2*MAX],head[MAX];
     22 
     23 //树链剖分模板
     24 //dfs1
     25 int dep[MAX];//节点的深度
     26 int fa[MAX];//节点的父亲节点
     27 int siz[MAX];//节点的儿子个数(子节点个数)
     28 int son[MAX];//节点的重儿子
     29 //dfs2
     30 int top[MAX];//这条链的顶端节点
     31 int tid[MAX];//按照链顺序的新编号
     32 int rank1[MAX];//新编号对应的原编号
     33 
     34 void addedge(int u,int v)
     35 {
     36     to[edge]=v,next1[edge]=head[u],head[u]=edge++;
     37     to[edge]=u,next1[edge]=head[v],head[v]=edge++;
     38 }
     39 
     40 
     41 void dfs1(int u,int father,int d)//分出重儿子
     42 {
     43     dep[u]=d;
     44     fa[u]=father;
     45     siz[u]=1;
     46     for(int i=head[u];~i;i=next1[i])
     47     {
     48         int v=to[i];
     49         if(v!=father)
     50         {
     51             dfs1(v,u,d+1);
     52             siz[u]+=siz[v];
     53             if(son[u]==-1||siz[v]>siz[son[u]])
     54             {
     55                 son[u]=v;
     56             }
     57         }
     58     }
     59 }
     60 
     61 void dfs2(int u,int tp)//连点成链
     62 {
     63     top[u]=tp;
     64     tid[u]=++tim;
     65     rank1[tid[u]]=u;
     66     if(son[u]==-1) return;
     67     dfs2(son[u],tp);
     68     for(int i=head[u];~i;i=next1[i])
     69     {
     70         int v=to[i];
     71         if(v!=son[u]&&v!=fa[u])
     72         {
     73             dfs2(v,v);
     74         }
     75     }
     76 }
     77 
     78 //线段树
     79 void pushup(int x)
     80 {
     81     tree[x].sum=tree[x*2].sum+tree[x*2+1].sum;
     82     //tree[x].sum=max(tree[x*2].sum,tree[x*2+1].sum);
     83     return;
     84 }
     85 
     86 void pushdown(int x)
     87 {
     88     int nval=tree[x].lazy;
     89     if(nval)
     90     {
     91         tree[x*2].sum+=(tree[x*2].r-tree[x*2].l+1)*nval;
     92         tree[x*2+1].sum+=(tree[x*2+1].r-tree[x*2+1].l+1)*nval;
     93         tree[x*2].lazy+=nval;
     94         tree[x*2+1].lazy+=nval;
     95         tree[x].lazy=0;
     96     }
     97     return;
     98 }
     99 
    100 void build(int l,int r,int x)
    101 {
    102     tree[x].l=l;
    103     tree[x].r=r;
    104     tree[x].sum=tree[x].lazy=0;
    105     if(l==r)
    106     {
    107         tree[x].sum=a[rank1[l]];
    108         return;
    109     }
    110     int mid=(l+r)/2;
    111     build(l,mid,x*2);
    112     build(mid+1,r,x*2+1);
    113     pushup(x);
    114     return;
    115 }
    116 
    117 int query(int mb,int x)
    118 {
    119     int nl=tree[x].l,nr=tree[x].r;
    120     if(nl==nr)
    121     {
    122         return tree[x].sum;
    123     }
    124     int mid=(nl+nr)/2;
    125     int ans=0;
    126     pushdown(x);
    127     if (mb>mid)ans=query(mb,x*2+1);
    128     else ans=query(mb,x*2);
    129     pushup(x);
    130     return ans;
    131 }
    132 
    133 void update(int l,int r,int val,int x)
    134 {
    135     int nl=tree[x].l,nr=tree[x].r;
    136     if(l<=nl&&r>=nr)
    137     {
    138         tree[x].sum+=(nr-nl+1)*val;
    139         tree[x].lazy+=val;
    140         return;
    141     }
    142     pushdown(x);
    143     int mid=(nl+nr)/2;
    144     if(l<=mid)update(l,r,val,x*2);
    145     if(r>mid)update(l,r,val,x*2+1);
    146     pushup(x);
    147     return;
    148 }
    149 
    150 void change(int x,int y,int val)
    151 {
    152     while(top[x]!=top[y])
    153     {
    154         if(dep[top[x]]<dep[top[y]])swap(x,y);
    155         update(tid[top[x]],tid[x],val,1);
    156         x=fa[top[x]];
    157     }
    158     if(dep[x]>dep[y])swap(x,y);
    159     update(tid[x],tid[y],val,1);
    160     return;
    161 }
    162 
    163 int main()
    164 {
    165     #ifndef ONLINE_JUDGE
    166     freopen("in.txt","r",stdin);
    167     #endif
    168     char ch[5];
    169     while(~scanf("%d%d%d",&n,&m,&p))
    170     {
    171         memset(head,-1,sizeof(head));
    172         memset(son,-1,sizeof(son));
    173         tim=0;
    174         edge=0;
    175         for(int i=1;i<=n;i++)
    176         {
    177             scanf("%d",&a[i]);
    178         }
    179         for(int i=1;i<=m;i++)
    180         {
    181             scanf("%d%d",&x1,&y1);
    182             addedge(x1,y1);
    183 
    184         }
    185         dfs1(1,0,0);
    186         dfs2(1,1);
    187         build(1,n,1);
    188         while(p--)
    189         {
    190             scanf("%s",ch);
    191             if(ch[0]=='Q')
    192             {
    193                 scanf("%d",&x1);
    194                 printf("%d
    ",query(tid[x1],1));
    195             }
    196             else
    197             {
    198                 scanf("%d%d%d",&x1,&y1,&z1);
    199                 if(ch[0]=='D')z1=-z1;
    200                 change(x1,y1,z1);
    201             }
    202         }
    203     }
    204     return 0;
    205 }
  • 相关阅读:
    typedef用法小结
    14种排序
    常用google产品
    去重排序
    双向链表
    IDEA上传一个项目到github
    IDEA上传一个项目到github
    Git的安装
    Hibernate 加载策略得总结
    hadoop -- fsck
  • 原文地址:https://www.cnblogs.com/yuehuo/p/6660509.html
Copyright © 2020-2023  润新知