• BZOJ 1036:树的统计Count(树链剖分)


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

    题意:中文题意。

    思路:也是普通的树链剖分。唯一注意的点是在change函数中

    1     while(top[u] != top[v]) {
    2         if(dep[top[u]] < dep[top[v]]) swap(u, v);
    3         if(type == 1) ans = max(ans, query(1, 1, tim, tid[top[u]], tid[u], type));
    4         else ans += query(1, 1, tim, tid[top[u]], tid[u], type);
    5         u = fa[top[u]];
    6     }

    这里的dep比较的是节点的top节点的深度,而不是直接比较节点的深度。因为这里WA了好久。只能说还未完全理解透细节。

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <cstring>
      5 #include <string>
      6 #include <cmath>
      7 #include <queue>
      8 #include <vector>
      9 using namespace std;
     10 #define N 30010
     11 #define INF 10000000000
     12 #define lson rt<<1, l, m
     13 #define rson rt<<1|1, m + 1, r
     14 
     15 struct node
     16 {
     17     int v, nxt, w;
     18 }edge[N*2];
     19 int top[N], tid[N], fa[N], son[N], siz[N], dep[N], rak[N], w[N], tim;
     20 int head[N], tot;
     21 struct T
     22 {
     23     long long sum;
     24     long long ma;
     25 }tree[N<<2];
     26 
     27 void init()
     28 {
     29     memset(head, -1, sizeof(head));
     30     memset(son, -1, sizeof(son));
     31     tot = tim = 0;
     32 }
     33 
     34 void add(int u, int v)
     35 {
     36     edge[tot].v = v; edge[tot].nxt = head[u]; head[u] = tot++;
     37 }
     38 
     39 void dfs1(int u, int f, int d)
     40 {
     41     siz[u] = 1;
     42     dep[u] = d;
     43     fa[u] = f;
     44     for(int i = head[u]; ~i; i = edge[i].nxt) {
     45         int v = edge[i].v;
     46         if(v == f) continue;
     47         dfs1(v, u, d + 1);
     48         siz[u] += siz[v];
     49         if(son[u] == -1 || siz[son[u]] < siz[v]) son[u] = v;
     50     }
     51 }
     52 
     53 void dfs2(int u, int tp)
     54 {
     55     top[u] = tp;
     56     tid[u] = ++tim;
     57     rak[tim] = u;
     58     if(son[u] == -1) return ;
     59     dfs2(son[u], tp);
     60     for(int i = head[u]; ~i; i = edge[i].nxt) {
     61         int v = edge[i].v;
     62         if(v != fa[u] && v != son[u]) dfs2(v, v);
     63     }
     64 }
     65 
     66 void pushup(int rt)
     67 {
     68     tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum;
     69     tree[rt].ma = max(tree[rt<<1].ma, tree[rt<<1|1].ma);
     70 }
     71 
     72 void build(int rt, int l, int r)
     73 {
     74     tree[rt].sum = 0;
     75     tree[rt].ma = 0;
     76     if(l == r) {
     77         tree[rt].sum = w[rak[l]];
     78         tree[rt].ma = w[rak[l]];
     79         return ;
     80     }
     81     int m = (l + r) >> 1;
     82     build(lson); build(rson);
     83     pushup(rt);
     84 }
     85 
     86 void update(int rt, int l, int r, int id, int val)
     87 {
     88     if(l == r && l == id) {
     89         tree[rt].sum = val;
     90         tree[rt].ma = val;
     91         return ;
     92     }
     93     int m = (l + r) >> 1;
     94     if(id <= m) update(lson, id, val);
     95     else update(rson, id, val);
     96     pushup(rt);
     97 }
     98 
     99 long long query(int rt, int l, int r, int L, int R, int type)
    100 {
    101     long long ans = 0;
    102     if(type == 1) ans = -INF;
    103     if(L <= l && r <= R) {
    104         if(type == 1) ans = max(ans, tree[rt].ma);
    105         else ans += tree[rt].sum;
    106         return ans;
    107     }
    108     int m = (l + r) >> 1;
    109     if(L <= m) {
    110         if(type == 1) ans = max(ans, query(lson, L, R, type));
    111         else ans += query(lson, L, R, type);
    112     }
    113     if(m < R) {
    114         if(type == 1) ans = max(ans, query(rson, L, R, type));
    115         else ans += query(rson, L, R, type);
    116     }
    117     return ans;
    118 }
    119 
    120 long long change(int u, int v, int type)
    121 {
    122     long long ans = 0;
    123     if(type == 1) ans = -INF;
    124     while(top[u] != top[v]) {
    125         if(dep[top[u]] < dep[top[v]]) swap(u, v);
    126         if(type == 1) ans = max(ans, query(1, 1, tim, tid[top[u]], tid[u], type));
    127         else ans += query(1, 1, tim, tid[top[u]], tid[u], type);
    128         u = fa[top[u]];
    129     }
    130     if(dep[u] > dep[v]) swap(u, v);
    131     if(type == 1) ans = max(ans, query(1, 1, tim, tid[u], tid[v], type));
    132     else ans += query(1, 1, tim, tid[u], tid[v], type);
    133     return ans;
    134 }
    135 
    136 int main()
    137 {
    138     int n, q;
    139     scanf("%d", &n);
    140     init();
    141     for(int i = 1; i < n; i++) {
    142         int u, v;
    143         scanf("%d%d", &u, &v);
    144         add(u, v); add(v, u);
    145     }
    146     for(int i = 1; i <= n; i++) scanf("%d", &w[i]);
    147     dfs1(1, 1, 1);
    148     dfs2(1, 1);
    149     build(1, 1, tim);
    150     // for(int i = 1; i <= n; i++) printf("tid[%d] : %d
    ", i, tid[i]);
    151     scanf("%d", &q);
    152     while(q--) {
    153         char s[10];
    154         int a, b;
    155         scanf("%s%d%d", s, &a, &b);
    156         if(s[0] == 'C') {
    157             update(1, 1, tim, tid[a], b);
    158         } else {
    159             int type = 1;
    160             if(s[1] == 'S') type = 2;
    161             printf("%lld
    ", change(a, b, type));
    162         }
    163     }
    164     return 0;
    165 }
  • 相关阅读:
    Java [leetcode 36]Valid Sudoku
    Java [leetcode 35]Search Insert Position
    java中正则表达式
    Java [leetcode 34]Search for a Range
    SSRS表达式里引用.net dll
    一个简单的批处理
    .NET大批量插入数据到Oracle
    AX2009里调用.NET DLL的效率问题
    生成折扣日记账
    python's twelth day for me
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6016649.html
Copyright © 2020-2023  润新知