1. 程式人生 > >NOI 2015 軟件包管理器

NOI 2015 軟件包管理器

tree {} HR sof uil else bsp font 包管理器

題目: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 軟件包管理器