Submission #00351
ソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | #include <iostream> #include <vector> #include <algorithm> #include <functional> #include <stack> #include <queue> struct HLD { using Tree = std::vector<std::vector< int >>; const Tree &tree; std::vector< int > parent; std::vector< int > head; std::vector< int > vid; HLD( const Tree &tree) : tree(tree) { const int n = tree.size(); const int root = 0; std::stack<std::pair< int , int >> stack; stack.emplace(root, 0); parent.assign(n, -1); head.assign(n, -1); vid.assign(n, -1); std::vector< int > heavy(n, -1); std::vector< int > size(n, 1); while (!stack.empty()) { const int u = stack.top().first; const int i = stack.top().second; if (i < tree[u].size()) { stack.top().second++; const int v = tree[u][i]; if (v != parent[u]) { parent[v] = u; stack.emplace(v, 0); } } else { stack.pop(); int max = 0; for ( int v : tree[u]) { if (v != parent[u]) { size[u] += size[v]; if (max < size[v]) { max = size[v]; heavy[u] = v; } } } } } std::stack< int > s; s.push(root); int now = 0; while (!s.empty()) { const int h = s.top(); s.pop(); for ( int i = h; i != -1; i = heavy[i]) { head[i] = h; vid[i] = now++; for ( int j : tree[i]) { if (j != parent[i] && j != heavy[i]) { s.push(j); } } } } } template < typename T> void foreach( int u, int v, T func) { while ( true ) { if (vid[u] > vid[v]) { std::swap(u, v); } if (head[u] != head[v]) { func(vid[head[v]], vid[v]); v = parent[head[v]]; } else { func(vid[u], vid[v]); break ; } } } int lca( int u, int v) { while ( true ) { if (vid[u] > vid[v]) { std::swap(u, v); } if (head[u] != head[v]) { v = parent[head[v]]; } else { return u; } } } }; template < typename T> struct BIT { std::vector<T> dat; BIT( int n) : dat(n + 1) {} void add( int k, T v) { k++; while (k < dat.size()) { dat[k] += v; k += k & -k; } } T sum( int k) { k++; T ret = 0; while (k > 0) { ret += dat[k]; k &= k - 1; } return ret; } }; int main() { int n, m; std::cin >> n >> m; std::vector<std::vector< int >> g(n); for ( int i = 0; i < n - 1; i++) { int u, v; scanf ( "%d %d" , &u, &v); u--; v--; g[u].push_back(v); g[v].push_back(u); } HLD hld(g); std::vector< int > dp(n); std::vector< int > s(m), t(m); std::vector<std::vector< int >> es(n); for ( int i = 0; i < m; i++) { scanf ( "%d %d" , &s[i], &t[i]); s[i]--; t[i]--; int l = hld.lca(s[i], t[i]); es[l].push_back(i); } BIT< int > bit(n); std::function< void ( int , int )> dfs = [&]( int u, int p) { int tmp = 0; for ( int v : g[u]) { if (v != p) { dfs(v, u); tmp += dp[v]; } } dp[u] = tmp; for ( int v : g[u]) { bit.add(hld.vid[u], dp[v]); } for ( int id : es[u]) { int len = 0; int val = 0; hld.foreach(s[id], t[id], [&]( int l, int r) { val += bit.sum(r) - bit.sum(l - 1); len += r - l + 1; }); dp[u] = std::max(dp[u], len + val); } bit.add(hld.vid[u], -dp[u]); }; dfs(0, -1); int ans = 0; for ( int i = 0; i < n; i++) { ans = std::max(ans, dp[i]); } std::cout << ans << std::endl; } |
ステータス
項目 | データ |
---|---|
問題 | 0006 - tree |
ユーザー名 | pekempey |
投稿日時 | 2017-07-07 22:56:56 |
言語 | C++17 |
状態 | Accepted |
得点 | 100 |
ソースコード長 | 3398 Byte |
最大実行時間 | 195 ms |
最大メモリ使用量 | 26308 KB |
セット
セット | 得点 | Cases | |
---|---|---|---|
1 | ALL | 100 / 100 | * |
テストケース
ファイル名 | 状態 | 実行時間 | メモリ使用量 | # |
---|---|---|---|---|
01_sample_01.in | AC | 13 ms | 476 KB |
1
|
01_sample_02.in | AC | 11 ms | 452 KB |
1
|
02_random_01.in | AC | 13 ms | 420 KB |
1
|
02_random_02.in | AC | 12 ms | 520 KB |
1
|
02_random_03.in | AC | 16 ms | 492 KB |
1
|
02_random_04.in | AC | 18 ms | 588 KB |
1
|
02_random_05.in | AC | 13 ms | 432 KB |
1
|
03_random_01.in | AC | 14 ms | 532 KB |
1
|
03_random_02.in | AC | 16 ms | 640 KB |
1
|
03_random_03.in | AC | 14 ms | 616 KB |
1
|
03_random_04.in | AC | 11 ms | 728 KB |
1
|
03_random_05.in | AC | 14 ms | 712 KB |
1
|
04_random_01.in | AC | 176 ms | 12960 KB |
1
|
04_random_02.in | AC | 175 ms | 13008 KB |
1
|
05_random_01.in | AC | 166 ms | 12996 KB |
1
|
05_random_02.in | AC | 153 ms | 13096 KB |
1
|
05_random_03.in | AC | 160 ms | 13068 KB |
1
|
05_random_04.in | AC | 158 ms | 13084 KB |
1
|
05_random_05.in | AC | 160 ms | 13096 KB |
1
|
06_random_01.in | AC | 195 ms | 26188 KB |
1
|
06_random_02.in | AC | 139 ms | 26308 KB |
1
|
06_random_03.in | AC | 153 ms | 26300 KB |
1
|
06_random_04.in | AC | 173 ms | 26280 KB |
1
|
06_random_05.in | AC | 164 ms | 26284 KB |
1
|
07_random_01.in | AC | 127 ms | 26148 KB |
1
|
08_handmake_01.in | AC | 18 ms | 620 KB |
1
|
08_handmake_02.in | AC | 16 ms | 588 KB |
1
|
08_handmake_03.in | AC | 15 ms | 556 KB |
1
|
08_handmake_04.in | AC | 14 ms | 656 KB |
1
|