BZOJ 2815: [ZJOI2012]灾难
呃,题面没了,大概就是给出一些生物之间的捕食关系,求灭绝树每个点的灾难值。
拓扑排序之后倒着加入点,动态维护fa[][]数组,倍增法求LCA,当然大佬愿意写动态树也是极好的……
1 #include <cstdio> 2 3 inline int nextChar(void) { 4 const int siz = 1024; 5 6 static char buf[siz]; 7 static char *hd = buf + siz; 8 static char *tl = buf + siz; 9 10 if (hd == tl) 11 fread(hd = buf, 1, siz, stdin); 12 13 return *hd++; 14 } 15 16 inline int nextInt(void) { 17 register int ret = 0; 18 register int neg = false; 19 register int bit = nextChar(); 20 21 for (; bit < 48; bit = nextChar()) 22 if (bit == '-')neg ^= true; 23 24 for (; bit > 47; bit = nextChar()) 25 ret = ret * 10 + bit - 48; 26 27 return neg ? -ret : ret; 28 } 29 30 const int siz = 800005; 31 32 int n; 33 34 int cnt[siz]; 35 36 int tot1; 37 int hd1[siz]; 38 int to1[siz]; 39 int nt1[siz]; 40 41 inline void add1(int u, int v) 42 { 43 nt1[tot1] = hd1[u]; to1[tot1] = v; hd1[u] = tot1++; 44 } 45 46 int tot2; 47 int hd2[siz]; 48 int to2[siz]; 49 int nt2[siz]; 50 51 inline void add2(int u, int v) 52 { 53 nt2[tot2] = hd2[u]; to2[tot2] = v; hd2[u] = tot2++; 54 } 55 56 int dep[siz], fa[siz][25]; 57 58 inline int lca(int a, int b) 59 { 60 if (a == -1) 61 return b; 62 63 if (dep[a] < dep[b]) 64 a ^= b ^= a ^= b; 65 66 for (int i = 24; i >= 0; --i) 67 if (dep[fa[a][i]] >= dep[b]) 68 a = fa[a][i]; 69 70 if (a == b) 71 return a; 72 73 for (int i = 24; i >= 0; --i) 74 if (fa[a][i] != fa[b][i]) 75 a = fa[a][i], 76 b = fa[b][i]; 77 78 return fa[a][0]; 79 } 80 81 int que[siz], head, tail; 82 83 int sz[siz]; 84 85 void dfs(int u) 86 { 87 for (int i = hd2[u]; ~i; i = nt2[i]) 88 dfs(to2[i]), sz[u] += sz[to2[i]]; 89 90 ++sz[u]; 91 } 92 93 signed main(void) 94 { 95 n = nextInt(); 96 97 for (int i = 0; i <= n; ++i) 98 hd1[i] = hd2[i] = -1; 99 100 for (int i = 1, t; i <= n; ++i) 101 while (t = nextInt(), t) 102 add1(i, t), ++cnt[t]; 103 104 for (int i = 1; i <= n; ++i) 105 if (!cnt[i])que[tail++] = i; 106 107 while (head != tail) 108 { 109 int u = que[head++], v; 110 111 for (int i = hd1[u]; ~i; i = nt1[i]) 112 if (!(--cnt[v = to1[i]]))que[tail++] = v; 113 } 114 115 for (int i = tail - 1; i >= 0; --i) 116 { 117 int u = que[i], v = -1; 118 119 for (int j = hd1[u]; ~j; j = nt1[j]) 120 v = lca(v, to1[j]); 121 122 if (v == -1)v = 0; 123 124 add2(v, u); 125 126 fa[u][0] = v; 127 128 dep[u] = dep[v] + 1; 129 130 for (int j = 1; j < 25; ++j) 131 fa[u][j] = fa[fa[u][j - 1]][j - 1]; 132 } 133 134 dfs(0); 135 136 for (int i = 1; i <= n; ++i) 137 printf("%d\n", sz[i] - 1); 138 }
@Author: YouSiki