训练地址

A:

树剖板子题

求最小值的时候要注意值是不是有负数,如果有,初值要置为$-INF$

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3  
  4 #define N 30010
  5 #define INF 0x3f3f3f3f
  6 int n, q, arr[N];
  7 vector <int> G[N];
  8  
  9 int fa[N], deep[N], sze[N], son[N], top[N], p[N], fp[N], cnt;
 10 void DFS(int u)
 11 {
 12     sze[u] = 1;
 13     for (auto v : G[u]) if (v != fa[u])
 14     {
 15         fa[v] = u;
 16         deep[v] = deep[u] + 1;
 17         DFS(v);
 18         sze[u] += sze[v];
 19         if (!son[u] || sze[v] > sze[son[u]]) son[u] = v;
 20     }
 21 }
 22  
 23 void getpos(int u, int sp)
 24 {
 25     top[u] = sp;
 26     p[u] = ++cnt;
 27     fp[cnt] = u;
 28     if (!son[u]) return;
 29     getpos(son[u], sp);
 30     for (auto v : G[u]) if (v != fa[u] && v != son[u])
 31         getpos(v, v);
 32 }
 33  
 34 namespace SEG
 35 {
 36     struct node
 37     {
 38         int Max, sum;
 39         node () {}
 40         node (int Max, int sum) : Max(Max), sum(sum) {}
 41         node operator + (const node &other) const { return node(max(Max, other.Max), sum + other.sum); }
 42     }a[N << 2], res;
 43     void build(int id, int l, int r)
 44     {
 45         if (l == r)
 46         {
 47             a[id] = node(arr[fp[l]], arr[fp[l]]);
 48             return;
 49         }
 50         int mid = (l + r) >> 1;
 51         build(id << 1, l, mid);
 52         build(id << 1 | 1, mid + 1, r);
 53         a[id] = a[id << 1] + a[id << 1 | 1];
 54     }
 55     void update(int id, int l, int r, int pos, int val)
 56     {
 57         if (l == r)
 58         {
 59             a[id] = node(val, val);
 60             return;
 61         }
 62         int mid = (l + r) >> 1;
 63         if (pos <= mid) update(id << 1, l, mid, pos, val);
 64         else update(id << 1 | 1, mid + 1, r, pos, val);
 65         a[id] = a[id << 1] + a[id << 1 | 1];
 66     }
 67     void query(int id, int l, int r, int ql, int qr)
 68     {
 69         if (l >= ql && r <= qr)
 70         {
 71             res = res + a[id];
 72             return;
 73         }
 74         int mid = (l + r) >> 1;
 75         if (ql <= mid) query(id << 1, l, mid, ql, qr);
 76         if (qr > mid) query(id << 1 | 1, mid + 1, r, ql, qr);
 77     }
 78 }
 79  
 80 void query(int u, int v)
 81 {
 82     while (top[u] != top[v])
 83     {
 84         if (deep[top[u]] < deep[top[v]]) swap(u, v);
 85         SEG::query(1, 1, n, p[top[u]], p[u]);
 86         u = fa[top[u]];
 87     }
 88     if (deep[u] > deep[v]) swap(u, v);
 89     SEG::query(1, 1, n, p[u], p[v]);
 90 }
 91  
 92 int main()
 93 {
 94     while (scanf("%d%d", &n, &q) != EOF)
 95     {
 96         cnt = 0;
 97         memset(son, 0, sizeof son);
 98         for (int i = 1; i <= n; ++i) scanf("%d", arr + i), G[i].clear();
 99         for (int i = 1, u, v; i < n; ++i)
100         {
101             scanf("%d%d", &u, &v);
102             G[u].push_back(v);
103             G[v].push_back(u);
104         }
105         DFS(1); getpos(1, 1); SEG::build(1, 1, n);
106         for (int i = 1, op, x, y; i <= q; ++i)
107         {
108             scanf("%d%d%d", &op, &x, &y);
109             if (op == 2) SEG::update(1, 1, n, p[x], y);
110             else
111             {
112                 SEG::res = SEG::node(-INF, 0);
113                 query(x, y);
114                 printf("%d\n", op == 0 ? SEG::res.Max : SEG::res.sum);
115             }  
116         }
117     }
118     return 0;
119 }
View Code

相关文章: