結果
問題 | No.2491 Pochi and A Warp Machine |
ユーザー | square1001 |
提出日時 | 2023-09-29 23:02:08 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 6,033 bytes |
コンパイル時間 | 2,969 ms |
コンパイル使用メモリ | 241,832 KB |
実行使用メモリ | 113,524 KB |
最終ジャッジ日時 | 2024-07-22 16:59:56 |
合計ジャッジ時間 | 14,700 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
10,752 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 1 ms
5,376 KB |
testcase_03 | AC | 2 ms
5,376 KB |
testcase_04 | AC | 2 ms
5,376 KB |
testcase_05 | AC | 3 ms
5,376 KB |
testcase_06 | AC | 2 ms
5,376 KB |
testcase_07 | AC | 2 ms
5,376 KB |
testcase_08 | AC | 2 ms
5,376 KB |
testcase_09 | AC | 31 ms
5,376 KB |
testcase_10 | AC | 31 ms
5,376 KB |
testcase_11 | AC | 32 ms
5,376 KB |
testcase_12 | AC | 31 ms
5,376 KB |
testcase_13 | AC | 31 ms
5,376 KB |
testcase_14 | AC | 1,652 ms
20,612 KB |
testcase_15 | AC | 586 ms
10,892 KB |
testcase_16 | AC | 394 ms
8,672 KB |
testcase_17 | AC | 1,967 ms
23,000 KB |
testcase_18 | AC | 1,411 ms
17,636 KB |
testcase_19 | TLE | - |
testcase_20 | -- | - |
testcase_21 | -- | - |
testcase_22 | -- | - |
testcase_23 | -- | - |
testcase_24 | -- | - |
testcase_25 | -- | - |
testcase_26 | -- | - |
testcase_27 | -- | - |
testcase_28 | -- | - |
testcase_29 | -- | - |
testcase_30 | -- | - |
testcase_31 | -- | - |
testcase_32 | -- | - |
testcase_33 | -- | - |
testcase_34 | -- | - |
testcase_35 | -- | - |
testcase_36 | -- | - |
testcase_37 | -- | - |
testcase_38 | -- | - |
testcase_39 | -- | - |
testcase_40 | -- | - |
testcase_41 | -- | - |
testcase_42 | -- | - |
ソースコード
#include <bits/stdc++.h> using namespace std; const int INF = 1012345678; struct edge { int va, vb; }; struct state { int depth, current, bottom; }; string to_string(const vector<int>& arr) { string res = "["; for (int i = 0; i < arr.size(); i++) { if (i != 0) { res += ", "; } res += to_string(arr[i]); } res += "]"; return res; } class fenwicktree { private: int n; map<int, long long> d; long long rangesum(int r) { long long ans = 0; for (int i = r; i >= 1; i -= i & (-i)) { ans += d[i]; } return ans; } public: fenwicktree() : n(0), d(map<int, long long>()) {} fenwicktree(int n_) : n(n_), d(map<int, long long>()) {} void add(int pos, long long x) { for (int i = pos + 1; i <= n; i += i & (-i)) { d[i] += x; } } long long rangesum(int l, int r) { if (l >= r) { return 0; } return rangesum(r) - rangesum(l); } }; void solve(int N, const vector<int>& P, const vector<edge>& E, const vector<int>& dlist, vector<long long>& ans) { // step #1. make graph vector<vector<int> > G(N); for (edge e : E) { G[e.va].push_back(e.vb); G[e.vb].push_back(e.va); } // step #2. find centroid int root = -1; vector<int> subsize(N, 1); auto find_centroid = [&](auto& self, int pos, int pre) -> void { bool flag = true; for (int i : G[pos]) { if (i != pre) { self(self, i, pos); subsize[pos] += subsize[i]; if (subsize[i] * 2 > N) { flag = false; } } } if (flag && subsize[pos] * 2 >= N) { root = pos; } }; find_centroid(find_centroid, 0, -1); // step #3. build tree vector<int> depth(N); vector<int> comp(N, -1); vector<vector<int> > child(N); auto build_tree = [&](auto& self, int pos, int pre) -> void { for (int i : G[pos]) { if (i != pre) { comp[i] = comp[pos]; depth[i] = depth[pos] + 1; child[pos].push_back(i); self(self, i, pos); } } }; int K = G[root].size(); child[root] = G[root]; for (int i = 0; i < K; i++) { comp[G[root][i]] = i; depth[G[root][i]] = 1; build_tree(build_tree, G[root][i], root); } // step #5. calculate answer passing root vector<int> ord(N); for (int i = 0; i < N; i++) { ord[i] = i; } sort(ord.begin(), ord.end(), [&](int va, int vb) { return P[va] > P[vb]; }); // cerr << "N = " << N << endl; // cerr << "centroid = " << root << endl; int Z = dlist.size() + 1; vector<fenwicktree> bit0(K + 1, fenwicktree(Z)); vector<fenwicktree> bit1(K + 1, fenwicktree(Z)); for (int i : ord) { int idx = P[i]; // cost1: dlist[target_idx - 1] // cost2: 1 + depth[i] + depth[target] // if dlist[target_idx - 1] - depth[target] - 1 >= depth[i], profit long long profit = 0; profit += bit1[K].rangesum(depth[i], Z); profit -= bit0[K].rangesum(depth[i], Z) * depth[i]; if (i != root) { profit -= bit1[comp[i]].rangesum(depth[i], Z); profit += bit0[comp[i]].rangesum(depth[i], Z) * depth[i]; } ans[idx] -= profit; int diff = (idx != 0 ? dlist[idx - 1] : 0) - depth[i] - 1; // cerr << "i = " << i << ": idx = " << idx << ", profit = " << profit << ", diff = " << diff << endl; if (diff >= 0) { bit0[K].add(diff, 1); bit1[K].add(diff, diff); if (i != root) { bit0[comp[i]].add(diff, 1); bit1[comp[i]].add(diff, diff); } } } // step #6. divide into subproblems vector<vector<int> > subcomp(K); for (int i = 0; i < N; i++) { if (i != root) { subcomp[comp[i]].push_back(i); } } vector<vector<int> > subp(K); vector<vector<edge> > sube(K); for (int i = 0; i < K; i++) { subp[i].resize(subcomp[i].size()); for (int j = 0; j < subcomp[i].size(); j++) { subp[i][j] = P[subcomp[i][j]]; } } for (int i = 0; i < N - 1; i++) { if (comp[E[i].va] == comp[E[i].vb]) { int id = comp[E[i].va]; int nva = lower_bound(subcomp[id].begin(), subcomp[id].end(), E[i].va) - subcomp[id].begin(); int nvb = lower_bound(subcomp[id].begin(), subcomp[id].end(), E[i].vb) - subcomp[id].begin(); sube[id].push_back(edge{nva, nvb}); } } for (int i = 0; i < K; i++) { solve(subcomp[i].size(), subp[i], sube[i], dlist, ans); } } vector<int> distances(int N, const vector<edge>& E, const vector<int>& S, const vector<int>& T) { vector<vector<int> > G(N); for (edge e : E) { G[e.va].push_back(e.vb); G[e.vb].push_back(e.va); } vector<int> par(N); vector<int> depth(N); auto build_tree = [&](auto& self, int pos, int pre) -> void { for (int i : G[pos]) { if (i != pre) { par[i] = pos; depth[i] = depth[pos] + 1; self(self, i, pos); } } }; build_tree(build_tree, 0, -1); int bits = (N >= 3 ? 32 - __builtin_clz(N - 1) : N); vector<vector<int> > spar(bits); spar[0] = par; spar[0][0] = 0; for (int i = 1; i < bits; i++) { spar[i].resize(N); for (int j = 0; j < N; j++) { spar[i][j] = spar[i - 1][spar[i - 1][j]]; } } auto lca = [&](int va, int vb) { if (depth[va] < depth[vb]) { swap(va, vb); } int d = depth[va] - depth[vb]; for (int i = 0; i < bits; i++) { if ((d >> i) & 1) { va = spar[i][va]; } } if (va == vb) { return va; } for (int i = bits - 1; i >= 0; i--) { if (spar[i][va] != spar[i][vb]) { va = spar[i][va]; vb = spar[i][vb]; } } return spar[0][va]; }; vector<int> ans(S.size()); for (int i = 0; i < S.size(); i++) { ans[i] = depth[S[i]] + depth[T[i]] - depth[lca(S[i], T[i])] * 2; // cerr << "N = " << N << ", S = " << S[i] << ", T = " << T[i] << ", ans = " << ans[i] << endl; } return ans; } int main() { cin.tie(0); ios::sync_with_stdio(false); int N; cin >> N; vector<edge> E(N - 1); for (int i = 0; i < N - 1; i++) { cin >> E[i].va >> E[i].vb; E[i].va -= 1; E[i].vb -= 1; } vector<int> P(N), A(N - 1), B(N - 1); for (int i = 0; i < N; i++) { P[i] = i; if (i != N - 1) { A[i] = i; B[i] = i + 1; } } vector<int> D = distances(N, E, A, B); long long dsum = 0; for (int i = 0; i < N - 1; i++) { dsum += D[i]; } vector<long long> ans(N, dsum); solve(N, P, E, D, ans); for (int i = 0; i < N; i++) { cout << ans[i] << '\n'; } return 0; }