結果
| 問題 |
No.399 動的な領主
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-05-02 14:17:53 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 164 ms / 2,000 ms |
| コード長 | 2,891 bytes |
| コンパイル時間 | 2,400 ms |
| コンパイル使用メモリ | 209,148 KB |
| 最終ジャッジ日時 | 2025-01-21 05:47:04 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 19 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using i64 = int64_t;
struct HeavyLightDecomposition {
vector<int> sz, par, depth;
vector<int> idx, revidx, hld, top;
vector<vector<int>> G;
int root;
bool is_built = false;
HeavyLightDecomposition(int n, int root = 0)
: sz(n), par(n), depth(n), idx(n), revidx(n), top(n), G(n), root(root) {}
void add_edge(int u, int v) {
G[u].push_back(v);
G[v].push_back(u);
}
void build() {
dfs(root);
dfs2(root);
is_built = true;
}
void dfs(int v, int p = -1) {
sz[v] = 1;
par[v] = p;
if (p >= 0) depth[v] = depth[p] + 1;
for (int &to : G[v]) {
if (to == p) continue;
dfs(to, v);
sz[v] += sz[to];
}
}
void dfs2(int v, int p = -1) {
idx[v] = hld.size();
revidx[hld.size()] = v;
hld.push_back(v);
int x = 0;
int heaviest = -1;
for (int &to : G[v]) {
if (to == p) continue;
if (x < sz[to]) {
x = sz[to];
heaviest = to;
}
}
if (heaviest < 0) return;
top[heaviest] = top[v];
dfs2(heaviest, v);
for (int &to : G[v]) {
if (to == heaviest || to == p) continue;
top[to] = to;
dfs2(to, v);
}
}
// return [l, r)s
vector<pair<int, int>> query(int u, int v) {
assert(is_built);
vector<pair<int, int>> ret;
while (top[u] != top[v]) {
if (depth[top[u]] > depth[top[v]]) swap(u, v);
ret.push_back({idx[top[v]], idx[v] + 1});
v = par[top[v]];
}
if (idx[u] > idx[v]) swap(u, v);
ret.push_back({idx[u], idx[v] + 1});
return ret;
}
i64 lca(int u, int v) {
assert(is_built);
while (top[u] != top[v]) {
if (depth[top[u]] > depth[top[v]]) swap(u, v);
v = par[top[v]];
}
if (idx[u] > idx[v]) swap(u, v);
return u;
}
};
void solve() {
int n;
cin >> n;
HeavyLightDecomposition hld(n);
for (int i = 0; i < n - 1; i++) {
int a, b;
cin >> a >> b;
a--;
b--;
hld.add_edge(a, b);
}
hld.build();
int q;
cin >> q;
vector<i64> dp(n + 1);
while (q--) {
int a, b;
cin >> a >> b;
a--;
b--;
auto segments = hld.query(a, b);
for (auto &[l, r] : segments) {
dp[l]++;
dp[r]--;
}
}
for (int i = 0; i < n; i++) {
dp[i + 1] += dp[i];
}
i64 ans = 0;
for (int i = 0; i < n; i++) {
ans += dp[i] * (dp[i] + 1) / 2;
}
cout << ans << endl;
}
int main() {
cin.tie(0);
ios::sync_with_stdio(false);
solve();
return 0;
}