結果
| 問題 |
No.1002 Twotone
|
| コンテスト | |
| ユーザー |
risujiroh
|
| 提出日時 | 2020-03-02 09:50:50 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,154 ms / 5,000 ms |
| コード長 | 3,336 bytes |
| コンパイル時間 | 2,379 ms |
| コンパイル使用メモリ | 186,272 KB |
| 実行使用メモリ | 45,280 KB |
| 最終ジャッジ日時 | 2024-10-13 20:56:31 |
| 合計ジャッジ時間 | 16,425 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 33 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
int main() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
int n, k;
cin >> n >> k;
vector<vector<int>> g(n), col(n);
for (int _ = n - 1; _--; ) {
int u, v, c;
cin >> u >> v >> c;
--u, --v;
g[u].push_back(v), col[u].push_back(c);
g[v].push_back(u), col[v].push_back(c);
}
vector<bool> be(n, true);
vector<int> sz(n), par(n);
auto centroids = [&](int r, int cur_n) {
vector<int> res;
auto dfs = [&](auto&& self, int v, int p) -> void {
sz[v] = 1, par[v] = p;
bool ok = true;
for (int u : g[v]) {
if (be[u] and u != p) {
self(self, u, v);
sz[v] += sz[u];
ok &= 2 * sz[u] <= cur_n;
}
}
if (ok and 2 * sz[v] >= cur_n) {
res.push_back(v);
}
};
dfs(dfs, r, -1);
return res;
};
vector<int> c1;
vector<pair<int, int>> c2;
auto dfs = [&](auto&& self, int v, int p, const vector<int>& cs) -> void {
if (cs.size() == 1) {
c1.push_back(cs[0]);
} else {
c2.emplace_back(cs[0], cs[1]);
}
for (int id = 0; id < (int)g[v].size(); ++id) {
int u = g[v][id], c = col[v][id];
if (be[u] and u != p) {
if (cs.size() == 1) {
if (c < cs[0]) {
self(self, u, v, {c, cs[0]});
} else if (cs[0] < c) {
self(self, u, v, {cs[0], c});
} else {
self(self, u, v, cs);
}
} else if (c == cs[0] or c == cs[1]) {
self(self, u, v, cs);
}
}
}
};
auto f11 = [&](int s, int t) {
long long res = 0;
for (int l = s, r = s; l < t; ++l) {
while (r < t and c1[r] <= c1[l]) {
++r;
}
res += t - r;
}
return res;
};
auto f12 = [&](int s1, int t1, int s2, int t2) {
vector<int> cs(2 * (t2 - s2));
for (int i = 0; i < (int)cs.size(); i += 2) {
tie(cs[i], cs[i + 1]) = c2[s2 + i / 2];
}
sort(begin(cs), end(cs));
long long res = 0;
int l = s1, r = s1;
for (int e : cs) {
while (l < t1 and c1[l] < e) {
++l;
}
while (r < t1 and c1[r] <= e) {
++r;
}
res += r - l;
}
return res;
};
auto f22 = [&](int s, int t) {
long long res = 0;
for (int l = s, r = s; l < t; ++l) {
while (r < t and c2[r] <= c2[l]) {
++r;
}
res += r - l - 1;
}
return res;
};
long long res = 0;
auto rec = [&](auto&& self, int c, int cur_n) -> void {
c = centroids(c, cur_n)[0];
be[c] = false;
for (int v : g[c]) {
if (be[v]) {
self(self, v, par[v] == c ? sz[v] : cur_n - sz[c]);
}
}
be[c] = true;
c1.clear(), c2.clear();
for (int id = 0; id < (int)g[c].size(); ++id) {
int v = g[c][id];
if (be[v]) {
int n1 = c1.size(), n2 = c2.size();
dfs(dfs, v, c, {col[c][id]});
sort(begin(c1) + n1, end(c1));
sort(begin(c2) + n2, end(c2));
res -= f12(n1, c1.size(), n2, c2.size());
res -= f22(n2, c2.size());
}
}
sort(begin(c1), end(c1));
sort(begin(c2), end(c2));
int n1 = c1.size(), n2 = c2.size();
res += c2.size();
res += f11(0, n1);
res += f12(0, n1, 0, n2);
res += f22(0, n2);
};
rec(rec, 0, n);
cout << res << '\n';
}
risujiroh