码迷,mamicode.com
首页 > 其他好文 > 详细

NOI 2015 软件包管理器

时间:2018-03-03 16:55:32      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:void   ble   www.   const   uil   ret   chain   can   swa   

题目:Luogu 2146

树剖裸题,对线段树的每个节点维护安装的数量和未安装的数量。

需要注意的是 maintain( ) 的时候若为叶子节点则返回

  1 #include <cstdio>
  2 #include <string>
  3 
  4 const int N = 100005;
  5 
  6 void swap(int &x, int &y) {
  7     x ^= y, y ^= x, x ^= y;
  8 }
  9 
 10 int read() {
 11     int x = 0, f = 1;
 12     char c = getchar();
 13     while (!isdigit(c)) {
 14         if (c == -) f = -1;
 15         c = getchar();
 16     }
 17     while (isdigit(c)) {
 18         x = (x << 3) + (x << 1) + (c ^ 48);
 19         c = getchar();
 20     }
 21     return x * f;
 22 }
 23 
 24 int head[N], pre[N], size[N], fa[N], deep[N], son[N], top[N], dfn[N], dfs_clock;
 25 
 26 struct Node {
 27     Node *ls, *rs;
 28     int tag, ins, uns;
 29     Node() : tag(0) {}
 30     void maintain() {
 31         if (!ls && !rs) return;
 32         ins = 0, uns = 0;
 33         if (ls) ins += ls->ins, uns += ls->uns;
 34         if (rs) ins += rs->ins, uns += rs->uns;
 35     }
 36 } Pool[N << 1], *root;
 37 
 38 Node *newNode() {
 39     static int cnt = 0;
 40     return &Pool[++cnt];
 41 }
 42 
 43 void build(Node *&cur, int l, int r) {
 44     if (!cur) cur = newNode();
 45     if (l == r) cur->ins = 0, cur->uns = 1;
 46     else {
 47         int mid = l + ((r - l) >> 1);
 48         build(cur->ls, l, mid);
 49         build(cur->rs, mid + 1, r);
 50         cur->maintain();
 51     }
 52 }
 53 
 54 void pushdown(Node *&cur, int l, int r) {
 55     if (cur->ls) {
 56         if (cur->tag == 1) cur->ls->ins += cur->ls->uns, cur->ls->uns = 0;
 57         else cur->ls->uns += cur->ls->ins, cur->ls->ins = 0;
 58         cur->ls->tag = cur->tag;
 59     }
 60     if (cur->rs) {
 61         if (cur->tag == 1) cur->rs->ins += cur->rs->uns, cur->rs->uns = 0;
 62         else cur->rs->uns += cur->rs->ins, cur->rs->ins = 0;
 63         cur->rs->tag = cur->tag;
 64     }
 65     cur->tag = 0;
 66 }
 67 
 68 int query(Node *&cur, int l, int r, int L, int R, int key) {
 69     if (!cur) return 0;
 70     if (L <= l && r <= R) {
 71         int ans = (key == 1 ? cur->ins : cur->uns);
 72         if (key == 1) cur->uns += cur->ins, cur->ins = 0;
 73         else cur->ins += cur->uns, cur->uns = 0;
 74         cur->tag = -key;
 75         return ans;
 76     }
 77     if (cur->tag) pushdown(cur, l, r);
 78     int mid = l + ((r - l) >> 1), ans = 0;
 79     if (L <= mid) ans += query(cur->ls, l, mid, L, R, key);
 80     if (mid < R) ans += query(cur->rs, mid + 1, r, L, R, key);
 81     cur->maintain();
 82     return ans;
 83 }
 84 
 85 int qchain(int x, int y) {
 86     int ans = 0;
 87     while (top[x] != top[y]) {
 88         if (deep[top[x]] < deep[top[y]]) swap(x, y);
 89         ans += query(root, 1, dfs_clock, dfn[top[x]], dfn[x], -1);
 90         x = fa[top[x]];
 91     }
 92     if (deep[x] > deep[y]) swap(x, y);
 93     ans += query(root, 1, dfs_clock, dfn[x], dfn[y], -1);
 94     return ans;
 95 }
 96 
 97 int qtree(int x) {
 98     return query(root, 1, dfs_clock, dfn[x], dfn[x] + size[x] - 1, 1);
 99 }
100 
101 void dfs1(int cur, int father, int depth) {
102     size[cur] = 1, fa[cur] = father, deep[cur] = depth, son[cur] = 0;
103     for (int nxt = head[cur]; nxt; nxt = pre[nxt]) {
104         if (nxt != father) {
105             dfs1(nxt, cur, depth + 1);
106             size[cur] += size[nxt];
107             if (size[nxt] > size[son[cur]]) son[cur] = nxt;
108         }
109     }
110 }
111 
112 void dfs2(int cur, int topth) {
113     dfn[cur] = ++dfs_clock, top[cur] = topth;
114     if (son[cur]) dfs2(son[cur], topth);
115     for (int nxt = head[cur]; nxt; nxt = pre[nxt]) {
116         if (nxt != fa[cur] && nxt != son[cur]) dfs2(nxt, nxt);
117     }
118 }
119 
120 int main() {
121     int n = read();
122     for (int v = 2; v <= n; ++ v) {
123         int u = read(); ++ u;
124         pre[v] = head[u], head[u] = v;
125     }
126     dfs1(1, 0, 1); dfs2(1, 1); build(root, 1, n);
127     int m = read(); char s[20] = {};
128     while (m--) {
129         scanf("%s", s); int x = read(); ++ x;
130         if (s[0] == i) {
131             printf("%d\n", qchain(0, x));
132         } else {
133             printf("%d\n", qtree(x));
134         }
135     }
136     return 0;
137 }

 

NOI 2015 软件包管理器

标签:void   ble   www.   const   uil   ret   chain   can   swa   

原文地址:https://www.cnblogs.com/milky-w/p/8496746.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!