• BZOJ 1036: [ZJOI2008]树的统计Count


    1036: [ZJOI2008]树的统计Count

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 8812  Solved: 3588

    Description

    一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. 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

    解题:树链剖分

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int maxn = 30010;
      4 struct arc {
      5     int to,next;
      6     arc(int x = 0,int y = -1) {
      7         to = x;
      8         next = y;
      9     }
     10 } e[maxn<<1];
     11 struct node {
     12     int lt,rt,sum,maxval;
     13 } tree[maxn<<2];
     14 int head[maxn],fa[maxn],top[maxn],dep[maxn];
     15 int siz[maxn],son[maxn],loc[maxn],clk,tot;
     16 void add(int u,int v) {
     17     e[tot] = arc(v,head[u]);
     18     head[u] = tot++;
     19 }
     20 void FindHeavyEdge(int u,int father,int depth) {
     21     fa[u] = father;
     22     dep[u] = depth;
     23     son[u] = -1;
     24     siz[u] = 1;
     25     for(int i = head[u]; ~i; i = e[i].next) {
     26         if(e[i].to == father) continue;
     27         FindHeavyEdge(e[i].to,u,depth + 1);
     28         siz[u] += siz[e[i].to];
     29         if(son[u] == -1 || siz[e[i].to] > siz[son[u]])
     30             son[u] = e[i].to;
     31     }
     32 }
     33 void ConnectHeavyEdge(int u,int ancestor) {
     34     loc[u] = clk++;
     35     top[u] = ancestor;
     36     if(son[u] != -1) ConnectHeavyEdge(son[u],ancestor);
     37     for(int i = head[u]; ~i; i = e[i].next) {
     38         if(e[i].to == fa[u] || son[u] == e[i].to) continue;
     39         ConnectHeavyEdge(e[i].to,e[i].to);
     40     }
     41 }
     42 void build(int lt,int rt,int v) {
     43     tree[v].lt = lt;
     44     tree[v].rt = rt;
     45     tree[v].sum = 0;
     46     tree[v].maxval = 0;
     47     if(lt == rt) return;
     48     int mid = (lt + rt)>>1;
     49     build(lt,mid,v<<1);
     50     build(mid + 1,rt,v<<1|1);
     51 }
     52 void update(int pos,int val,int v) {
     53     if(tree[v].lt == tree[v].rt) {
     54         tree[v].maxval = tree[v].sum = val;
     55         return;
     56     }
     57     if(pos <= tree[v<<1].rt) update(pos,val,v<<1);
     58     if(pos >= tree[v<<1|1].lt) update(pos,val,v<<1|1);
     59     tree[v].sum = tree[v<<1].sum + tree[v<<1|1].sum;
     60     tree[v].maxval = max(tree[v<<1].maxval,tree[v<<1|1].maxval);
     61 }
     62 int querySum(int lt,int rt,int v) {
     63     if(lt <= tree[v].lt && rt >= tree[v].rt) return tree[v].sum;
     64     int ret = 0;
     65     if(lt <= tree[v<<1].rt) ret = querySum(lt,rt,v<<1);
     66     if(rt >= tree[v<<1|1].lt) ret += querySum(lt,rt,v<<1|1);
     67     return ret;
     68 }
     69 int queryMax(int lt,int rt,int v) {
     70     if(lt <= tree[v].lt && rt >= tree[v].rt) return tree[v].maxval;
     71     int ret = -0x3f3f3f3f;
     72     if(lt <= tree[v<<1].rt) ret = queryMax(lt,rt,v<<1);
     73     if(rt >= tree[v<<1|1].lt) ret = max(ret,queryMax(lt,rt,v<<1|1));
     74     return ret;
     75 }
     76 int sum(int a,int b) {
     77     return a + b;
     78 }
     79 int mymax(int a,int b) {
     80     return max(a,b);
     81 }
     82 int CAO(int u,int v,int (*f)(int,int,int),int (*g)(int,int),int ret = 0) {
     83     while(top[u] != top[v]) {
     84         if(dep[top[u]] < dep[top[v]]) swap(u,v);
     85         ret = g(ret,f(loc[top[u]],loc[u],1));
     86         u = fa[top[u]];
     87     }
     88     if(dep[u] > dep[v]) swap(u,v);
     89     ret = g(ret,f(loc[u],loc[v],1));
     90     return ret;
     91 }
     92 int main() {
     93     int n,m,u,v;
     94     while(~scanf("%d",&n)) {
     95         memset(head,-1,sizeof head);
     96         tot = clk = 0;
     97         for(int i = 1; i < n; ++i) {
     98             scanf("%d%d",&u,&v);
     99             add(u,v);
    100             add(v,u);
    101         }
    102         FindHeavyEdge(1,0,0);
    103         ConnectHeavyEdge(1,1);
    104         build(0,clk-1,1);
    105         for(int i = 1; i <= n; ++i){
    106             scanf("%d",&u);
    107             update(loc[i],u,1);
    108         }
    109         scanf("%d",&m);
    110         char op[20];
    111         while(m--){
    112             scanf("%s",op);
    113             if(op[1] == 'S'){
    114                 scanf("%d%d",&u,&v);
    115                 printf("%d
    ",CAO(u,v,querySum,sum,0));
    116             }else if(op[1] == 'H'){
    117                 scanf("%d%d",&u,&v);
    118                 update(loc[u],v,1);
    119             }else if(op[1] == 'M'){
    120                 scanf("%d%d",&u,&v);
    121                 printf("%d
    ",CAO(u,v,queryMax,mymax,-0x3f3f3f3f));
    122             }
    123         }
    124     }
    125     return 0;
    126 }
    127 /*
    128 4
    129 1 2
    130 2 3
    131 4 1
    132 4 2 1 3
    133 12
    134 QMAX 3 4
    135 QMAX 3 3
    136 QMAX 3 2
    137 QMAX 2 3
    138 QSUM 3 4
    139 QSUM 2 1
    140 CHANGE 1 5
    141 QMAX 3 4
    142 CHANGE 3 6
    143 QMAX 3 4
    144 QMAX 2 4
    145 QSUM 3 4
    146 */
    View Code
  • 相关阅读:
    再深一点:如何给女朋友解释什么是微服务?
    图文详解:内存总是不够,我靠HBase说服了Leader为新项目保驾护航
    Java多态总结
    猴子吃桃问题(南阳ACM324)
    杭电acm-2007平方和立方和
    出现错误,修改后的
    今天的第一个程序-南阳acm输入三个数排序
    Azure Blob上传和下载
    用Aspose.Cells把Excel文件转成PDF
    Ionic IOS打包第二节
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4845484.html
Copyright © 2020-2023  润新知