zoukankan      html  css  js  c++  java
  • BZOJ_1036_[ZJOI2008]_树的统计Conut_(树链剖分)

    描述


    http://www.lydsy.com/JudgeOnline/problem.php?id=1036

    给出一棵树以及各点的权值,对数进行如下三种操作:

    1.改变某一节点u的值为t;

    2.求节点u到节点v之间(包括u与v)的最大值;

    3.求节点u到节点v之间(包括u与v)的和.

    1036: [ZJOI2008]树的统计Count

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 12002  Solved: 4864
    [Submit][Status][Discuss]

    Description

      一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成
    一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I
    II. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身

    Input

      输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有
    一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作
    的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。
    对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。

    Output

      对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。

    Sample Input

    4
    1 2
    2 3
    4 1
    4 2 1 3
    12
    QMAX 3 4
    QMAX 3 3
    QMAX 3 2
    QMAX 2 3
    QSUM 3 4
    QSUM 2 1
    CHANGE 1 5
    QMAX 3 4
    CHANGE 3 6
    QMAX 3 4
    QMAX 2 4
    QSUM 3 4

    Sample Output

    4
    1
    2
    2
    10
    6
    5
    6
    5
    16

    HINT

    Source

    分析


    树链剖分模板题,但貌似LCA写得太原始了= =,并不会其他方法.直接裸的原始LCA好像可以过两个点...

    注意:

    1.对u,v进行操作时是判断tib[u]与tib[v]的大小,不然上线段树会炸.(tib[top[u]]<=tib[u]恒成立)

    2.在LCA时别少写了dep[top[u]]==dep[top[v]]的情况.

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <vector>
      4 #include <algorithm>
      5 #define read(a) a=getnum()
      6 #define lson (2*k)
      7 #define rson (2*k+1)
      8 #define mid ((a[k].l+a[k].r)>>1)
      9  
     10 using namespace std;
     11  
     12 const int maxn=30000+5,INF=30000+5;
     13  
     14 struct node
     15 {
     16     int l,r,k,x,m;
     17 };
     18  
     19 int n,q;
     20 int label;
     21 int w[maxn];
     22 int fa[maxn];
     23 int dep[maxn];
     24 int size[maxn];
     25 int son[maxn];
     26 int top[maxn];
     27 int tib[maxn];
     28 int rev_tib[maxn];
     29 bool vis1[maxn];
     30 bool vis2[maxn];
     31 vector <int> g1[maxn];
     32 vector <int> g2[maxn];
     33 node  a[3*maxn];
     34  
     35 inline int  getnum()
     36 {
     37     int r=0,k=1;
     38     char c;
     39     for(c=getchar();c<'0'||c>'9';c=getchar()) if(c=='-') k=-1;
     40     for(;c>='0'&&c<='9';c=getchar()) r=r*10+c-'0';
     41     return r*k;
     42 }
     43  
     44 void build_tree(int l,int r,int k)
     45 {
     46     a[k].l=l; a[k].r=r; 
     47     if(l==r)
     48     {
     49         a[k].x=a[k].m=w[rev_tib[l]];
     50         return;
     51     }
     52     build_tree(l,mid,lson);
     53     build_tree(mid+1,r,rson);
     54     a[k].x=a[lson].x+a[rson].x;
     55     a[k].m=max(a[lson].m,a[rson].m);
     56 }
     57  
     58 void update(int x,int t,int k)
     59 {
     60     if(a[k].l==a[k].r&&a[k].l==x)
     61     {
     62         a[k].x=a[k].m=t;
     63         return;
     64     }
     65     if(x<=mid) update(x,t,lson);
     66     else update(x,t,rson);
     67     a[k].x=a[lson].x+a[rson].x;
     68     a[k].m=max(a[lson].m,a[rson].m);
     69 }
     70  
     71 int get_max(int l,int r,int k)
     72 {
     73     if(l==a[k].l&&r==a[k].r)
     74     {
     75         return a[k].m;
     76     }
     77     if(r<=mid) return get_max(l,r,lson);
     78     else if(l>mid) return get_max(l,r,rson);
     79     else return max(get_max(l,mid,lson),get_max(mid+1,r,rson));
     80 }
     81  
     82 int get_sum(int l,int r,int k)
     83 {
     84     if(l==a[k].l&&r==a[k].r)
     85     {
     86         return a[k].x;
     87     }
     88     if(r<=mid) return get_sum(l,r,lson);
     89     else if(l>mid) return get_sum(l,r,rson);
     90     else return get_sum(l,mid,lson)+get_sum(mid+1,r,rson);
     91 }
     92  
     93  
     94 void find_h_e(int u,int father,int depth)
     95 {
     96     vis1[u]=true;
     97     fa[u]=father;
     98     dep[u]=depth;
     99     size[u]=1;
    100     son[u]=0;
    101     int max_size=0;
    102     for(int i=0;i<g1[u].size();i++)
    103     {
    104         int v=g1[u][i];
    105         if(vis1[v]) continue;
    106         g2[u].push_back(v);
    107         find_h_e(v,u,depth+1);
    108         size[u]+=size[v];
    109         if(size[v]>max_size)
    110         {
    111             max_size=size[v];
    112             son[u]=v;
    113         }
    114     }
    115 }
    116  
    117 void conect_h_e(int u,int ancestor)
    118 {
    119     vis2[u]=true;
    120     top[u]=ancestor;
    121     tib[u]=++label;
    122     rev_tib[label]=u;
    123     if(son[u])
    124     {
    125         conect_h_e(son[u],ancestor);
    126     }
    127     for(int i=0;i<g2[u].size();i++)
    128     {
    129         int v=g2[u][i];
    130         if(vis2[v]) continue;
    131         conect_h_e(v,v);
    132     }
    133 }
    134  
    135 void Change(int u,int t)
    136 {
    137     update(tib[u],t,1);
    138 }
    139  
    140 int Q_max(int u,int v)
    141 {
    142     int max_now=-INF;
    143     while(top[u]!=top[v])
    144     {
    145         if(dep[top[u]]==dep[top[v]])
    146         {
    147             max_now=max(max_now,get_max(tib[top[u]],tib[u],1));
    148             u=fa[top[u]];
    149             continue;
    150         }
    151         while(dep[top[u]]>dep[top[v]])
    152         {
    153             max_now=max(max_now,get_max(tib[top[u]],tib[u],1));
    154             u=fa[top[u]];
    155         }
    156         while(dep[top[u]]<dep[top[v]])
    157         {
    158             max_now=max(max_now,get_max(tib[top[v]],tib[v],1));
    159             v=fa[top[v]];
    160         }
    161     }
    162     max_now=max(max_now,get_max(min(tib[v],tib[u]),max(tib[u],tib[v]),1));
    163     return max_now;
    164 }
    165  
    166 int Q_sum(int u,int v)
    167 {
    168     int sum_now=0;
    169     while(top[u]!=top[v])
    170     {
    171         if(dep[top[u]]==dep[top[v]])
    172         {
    173             sum_now+=get_sum(tib[top[u]],tib[u],1);
    174             u=fa[top[u]];
    175             continue;
    176         }
    177         while(dep[top[u]]>dep[top[v]])
    178         {
    179             sum_now+=get_sum(tib[top[u]],tib[u],1);
    180             u=fa[top[u]];
    181         }
    182         while(dep[top[u]]<dep[top[v]])
    183         {
    184             sum_now+=get_sum(tib[top[v]],tib[v],1);
    185             v=fa[top[v]];
    186         }
    187     }
    188     sum_now+=get_sum(min(tib[v],tib[u]),max(tib[u],tib[v]),1);
    189     return sum_now;
    190 }
    191  
    192 void init()
    193 {
    194     read(n);
    195     for(int i=1;i<n;i++)
    196     {
    197         int u,v;
    198         read(u); read(v);
    199         g1[u].push_back(v);
    200         g1[v].push_back(u);
    201     }
    202     for(int i=1;i<=n;i++)
    203     {
    204         read(w[i]);
    205     }
    206 }
    207  
    208 int main()
    209 {
    210     init();
    211     read(q);
    212     find_h_e(1,0,1);
    213     conect_h_e(1,1);
    214     build_tree(1,n,1);
    215     for(int i=1;i<=q;i++)
    216     {
    217         char c;
    218         c=getchar();
    219         if(c=='C')
    220         {
    221             int u,t;
    222             read(u); read(t);
    223             Change(u,t);
    224         }
    225         else
    226         {
    227             c=getchar();
    228             if(c=='M')
    229             {
    230                 int u,v;
    231                 read(u); read(v);
    232                 printf("%d
    ",Q_max(u,v));
    233             }
    234             else
    235             {
    236                 int u,v;
    237                 read(u); read(v);
    238                 printf("%d
    ",Q_sum(u,v));
    239             }
    240         }
    241     }
    242     return 0;
    243 }
    View Code
  • 相关阅读:
    gcc和g++的区别和联系
    Linux基础命令第二天
    Linux基础命令第一天
    Flask入门之完整项目搭建
    Flask入门第三天
    Flask入门第二天
    Flask入门第一天
    vue_drf之多级过滤、排序、分页
    vue_drf之视频接口
    vue_drf之支付宝接口
  • 原文地址:https://www.cnblogs.com/Sunnie69/p/5460753.html
Copyright © 2011-2022 走看看