結果
| 問題 |
No.399 動的な領主
|
| コンテスト | |
| ユーザー |
kazuma
|
| 提出日時 | 2018-07-03 02:33:47 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 256 ms / 2,000 ms |
| コード長 | 3,028 bytes |
| コンパイル時間 | 2,628 ms |
| コンパイル使用メモリ | 209,064 KB |
| 最終ジャッジ日時 | 2025-01-06 11:49:18 |
|
ジャッジサーバーID (参考情報) |
judge2 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 19 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
class heavy_light_decomposition {
const int n;
vector<vector<int>> g;
vector<int> in, out, head, par;
public:
heavy_light_decomposition(int n_)
: n(n_), g(n), in(n, -1), out(n, -1), head(n), par(n, -1) {}
heavy_light_decomposition(const vector<vector<int>>& G)
: n(G.size()), g(G), in(n, -1), out(n, -1), head(n), par(n, -1) {}
void add_edge(int u, int v) {
g[u].push_back(v);
g[v].push_back(u);
}
void build(int rt = 0) {
vector<int> size(n, 1);
vector<int> iter(n);
vector<pair<int, int>> stp; stp.reserve(n);
stp.emplace_back(rt, -1);
while (!stp.empty()) {
int v = stp.back().first, prev = stp.back().second;
if (iter[v] < (int)g[v].size()) {
if (g[v][iter[v]] != prev) stp.emplace_back(g[v][iter[v]], v);
++iter[v];
continue;
}
par[v] = prev;
for (auto& u : g[v]) if (u == prev) {
if (u != g[v].back()) swap(u, g[v].back());
g[v].pop_back();
break;
}
for (auto& u : g[v]) {
size[v] += size[u];
if (size[u] > size[g[v].front()]) swap(u, g[v].front());
}
stp.pop_back();
}
fill(iter.begin(), iter.end(), 0);
int it = 0;
vector<int> st; st.reserve(n);
head[rt] = rt;
st.push_back(rt);
while (!st.empty()) {
int v = st.back();
if (!iter[v]) in[v] = it++;
if (iter[v] < (int)g[v].size()) {
int u = g[v][iter[v]];
head[u] = iter[v] ? u : head[v];
st.push_back(u);
++iter[v];
continue;
}
out[v] = it;
st.pop_back();
}
}
void path_query(int u, int v, function<void(int, int)> f) {
while (true) {
if (in[u] > in[v]) swap(u, v);
f(max(in[head[v]], in[u]), in[v] + 1);
if (head[u] == head[v]) return;
v = par[head[v]];
}
}
};
template <typename T>
class fenwick_tree {
const int n;
vector<T> data;
public:
fenwick_tree(int n_) : n(n_), data(n) {}
T find(int p) const {
T res = 0;
while (p >= 0) {
res += data[p];
p = (p & (p + 1)) - 1;
}
return res;
}
void add(int p, T val) {
while (p < n) {
data[p] += val;
p |= p + 1;
}
}
};
template <typename T>
class range_add_range_sum {
const int n;
fenwick_tree<T> bit0, bit1;
public:
range_add_range_sum(int n_) : n(n_), bit0(n), bit1(n) {}
T find(int p) const {
return bit1.find(p) * (p + 1) + bit0.find(p);
}
T find(int l, int r) const {
return find(r - 1) - find(l - 1);
}
void add(int l, int r, T val) {
bit0.add(l, -val * l);
bit1.add(l, val);
bit0.add(r, val * r);
bit1.add(r, -val);
}
};
int main()
{
ios::sync_with_stdio(false), cin.tie(0);
ll N, Q, A, B;
cin >> N;
heavy_light_decomposition hl(N);
for (int i = 0; i < N - 1; i++) {
int u, v;
cin >> u >> v; u--, v--;
hl.add_edge(u, v);
}
hl.build();
range_add_range_sum<ll> ra(N);
cin >> Q;
ll res = 0;
while (Q--) {
cin >> A >> B; A--; B--;
hl.path_query(A, B, [&](int l, int r) {
res += ra.find(l, r) + (r - l);
});
hl.path_query(A, B, [&](int l, int r) {
ra.add(l, r, 1);
});
}
cout << res << endl;
return 0;
}
kazuma