zoukankan      html  css  js  c++  java
  • BZOJ1036: [ZJOI2008]树的统计Count

    1036: [ZJOI2008]树的统计Count

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 20055  Solved: 8146
    [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

    树链剖分模板题

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 #include <queue>
      7 #include <vector>
      8 #define min(a, b) ((a) < (b) ? (a) : (b))
      9 #define max(a, b) ((a) > (b) ? (a) : (b))
     10 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
     11 inline void swap(int &a, int &b){int tmp = a;a = b;b = tmp;}
     12 inline void read(int &x)
     13 {
     14     x = 0;char ch = getchar(), c = ch;
     15     while(ch < '0' || ch > '9') c = ch, ch = getchar();
     16     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
     17     if(c == '-') x = -x;
     18 }
     19 const int INF = 0x3f3f3f3f;
     20 const int MAXN = 100000 + 10;
     21 struct Edge
     22 {
     23     int u,v,nxt;
     24     Edge(int _u, int _v, int _nxt){u = _u;v = _v;nxt = _nxt;}
     25     Edge(){}
     26 }edge[MAXN << 1];
     27 int head[MAXN], cnt;
     28 inline void insert(int a, int b)
     29 {
     30     edge[++cnt] = Edge(a,b,head[a]);
     31     head[a] = cnt;
     32 }
     33 int n,q,tim,w[MAXN],size[MAXN],top[MAXN],son[MAXN],deep[MAXN],fa[MAXN],tid[MAXN],rank[MAXN];
     34 void dfs1(int u)
     35 {
     36     size[u] = 1;
     37     for(register int pos = head[u];pos;pos = edge[pos].nxt)
     38     {
     39         int v = edge[pos].v;
     40         if(v == fa[u]) continue;
     41         deep[v] = deep[u] + 1, fa[v] = u;
     42         dfs1(v);
     43         size[u] += size[v];
     44         if(son[u] == -1 || size[v] > size[son[u]]) son[u] = v;
     45     }
     46 }
     47 void dfs2(int u, int tp)
     48 {
     49     top[u] = tp, tid[u] = ++ tim, rank[tim] = u;
     50     if(son[u] == -1) return;
     51     dfs2(son[u], tp);
     52     for(register int pos = head[u];pos;pos = edge[pos].nxt)
     53     {
     54         int v = edge[pos].v;
     55         if(v != son[u] && v != fa[u]) dfs2(v, v);
     56     }
     57 }
     58 
     59 struct Node
     60 {
     61     int l,r,ma,sum,lazy;
     62     Node(){l = r = ma = sum = lazy = 0;}
     63 }node[MAXN << 2];
     64 
     65 Node merge(Node &a, Node &b)
     66 {
     67     Node re;
     68     if(a.l == 0) return b;
     69     else if(b.l == 0) return a;
     70     re.l = a.l, re.r = b.r;
     71     re.ma = max(a.ma, b.ma);
     72     re.sum = a.sum + b.sum;
     73     return re;
     74 }
     75 
     76 void pushup(Node &a, Node &l, Node &r)
     77 {
     78     if(a.lazy)
     79     {
     80         l.sum += (l.r - l.l + 1) * a.lazy;
     81         r.sum += (r.r - r.l + 1) * a.lazy;
     82         l.lazy += a.lazy;
     83         r.lazy += a.lazy;
     84         l.ma += a.lazy;
     85         r.ma += a.lazy;
     86         a.lazy = 0;
     87     }
     88 }
     89 
     90 void build(int o = 1, int l = 1, int r = n)
     91 {
     92     node[o].l = l, node[o].r = r;
     93     if(l == r)
     94     {
     95         node[o].ma = node[o].sum = w[rank[l]];
     96         return;
     97     }
     98     int mid = (l + r) >> 1;
     99     build(o << 1, l, mid);
    100     build(o << 1 | 1, mid + 1, r);
    101     node[o] = merge(node[o << 1], node[o << 1 | 1]);
    102     return;
    103 }
    104 
    105 void modify(int ll, int rr, int k, int o = 1)
    106 {
    107     pushup(node[o], node[o << 1], node[o << 1 | 1]);
    108     if(ll <= node[o].l && rr >= node[o].r)
    109     {
    110         node[o].ma += k;
    111         node[o].sum += (node[o].r - node[o].l + 1) * k;
    112         node[o].lazy += k;
    113         return;
    114     }
    115     int mid = (node[o].l + node[o].r) >> 1;
    116     if(mid >= ll) modify(ll, rr, k, o << 1);
    117     if(mid < rr) modify(ll, rr, k, o << 1 | 1);
    118     node[o] = merge(node[o << 1], node[o << 1 | 1]); 
    119     return;
    120 }
    121 
    122 Node ask(int ll, int rr, int o = 1)
    123 {
    124     pushup(node[o], node[o << 1], node[o << 1 | 1]);
    125     if(ll <= node[o].l && rr >= node[o].r) return node[o];
    126     Node a,b;a.l= -1, b.l = -1;
    127     int mid = (node[o].l + node[o].r) >> 1;
    128     if(mid >= ll) a = ask(ll, rr,o << 1);
    129     if(mid < rr) b = ask(ll, rr, o << 1 | 1);
    130     if(a.l == -1) return b;
    131     else if(b.l == -1) return a;
    132     else return merge(a, b);
    133 }
    134 
    135 Node find(int x, int y)
    136 {
    137     int f1 = top[x], f2 = top[y];
    138     Node tmp;
    139     Node re;
    140     while(f1 != f2)
    141     {
    142         if(deep[f1] < deep[f2]) swap(f1, f2), swap(x, y);
    143         tmp = ask(tid[f1], tid[x]);
    144         re = merge(re, tmp);
    145         x = fa[f1];f1 = top[x];
    146     }
    147     if(x == y) 
    148     {
    149         tmp = ask(tid[x], tid[x]);
    150         return merge(re, tmp);
    151     }
    152     if(deep[x] > deep[y]) swap(x, y);
    153     tmp = ask(tid[x], tid[y]);
    154     return merge(re, tmp);
    155 }
    156 
    157 char s[20];
    158 
    159 int main()
    160 {
    161     read(n);
    162     for(register int i = 1;i < n;++ i)
    163     {
    164         int tmp1,tmp2,tmp3;
    165         read(tmp1), read(tmp2);
    166         insert(tmp1, tmp2), insert(tmp2, tmp1);
    167     }
    168     for(register int i = 1;i <= n;++ i) read(w[i]);
    169     memset(son, -1, sizeof(son));
    170     dfs1(1);
    171     dfs2(1, 1);
    172     build();
    173     read(q);Node tmp;
    174     for(register int i = 1;i <= q;++ i)
    175     {
    176         int tmp1,tmp2;
    177         scanf("%s", s + 1);read(tmp1), read(tmp2);
    178         if(s[1] == 'C') modify(tid[tmp1], tid[tmp1], tmp2 - w[tmp1]), w[tmp1] = tmp2;
    179         else
    180         {    
    181             tmp = find(tmp1, tmp2);
    182             if(s[2] == 'M') printf("%d
    ", tmp.ma);
    183             else printf("%d
    ", tmp.sum);
    184         }
    185     }
    186     return 0;
    187 }
    BZOJ1036
  • 相关阅读:
    OLT配置学习
    notepad配合正则表达式处理文本
    利用expect和sshpass完美非交互性执行远端命令
    yum 数据库报错与重构
    杀死dialog
    OLT配置说明
    freeradius下发限速信息字段
    debug调试日志和数据查询
    通过windows的超级终端连接华为交换机
    强制清除交换机端口所有配置
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/8305160.html
Copyright © 2011-2022 走看看