QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#445283 | #8547. Whose Land? | ucup-team228 | WA | 0ms | 16104kb | C++20 | 5.5kb | 2024-06-16 00:48:41 | 2024-06-16 00:48:41 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template <typename T>
struct segment_tree {
static const int N = 1e5 + 10;
const T inf = numeric_limits<T>::max() / 2;
T t[2 * N + 10];
void build() {
for (int i = N - 1; i > 0; i--) {
t[i] = t[i << 1] + t[i << 1 | 1];
}
}
void update(int pos, T val) {
for (t[pos += N] += val; pos > 1; pos >>= 1) {
t[pos >> 1] = t[pos] + t[pos ^ 1];
}
}
T get(int l, int r) {
T res = 0;
for (l += N, r += N; l <= r; l >>= 1, r >>= 1) {
if (l & 1) res += t[l++];
if (!(r & 1)) res += t[r--];
}
return res;
}
};
segment_tree<int> tree;
const int inf = 1e9 + 10;
const int N = 1e5 + 10;
const int K = 20 + 2;
const int Q = 5e5 + 10;
vector<int> g[N];
int depth[N], par[N];
int ord[N], pos[N];
int lef_down[N][K], rig_down[N][K], lef_up[N][K], rig_up[N][K];
pair<int, int> que[Q];
vector<int> scn[N];
int ans[Q];
struct Segment {
int l, r, val;
bool operator<(const Segment& ot) const {
return tie(l, r, val) < tie(ot.l, ot.r, ot.val);
}
};
void init(int n, int k) {
for (int i = 1; i <= n; i++) {
g[i].clear();
depth[i] = 0;
pos[i] = 0;
ord[i] = 0;
par[i] = 0;
for (int j = 0; j <= k; j++) {
lef_down[i][j] = inf;
rig_down[i][j] = -inf;
lef_up[i][j] = inf;
rig_up[i][j] = -inf;
}
scn[i].clear();
tree.update(i, -tree.get(i, i));
}
}
void dfs(int v, int p) {
for (int to : g[v]) {
if (to != p) {
par[to] = v;
depth[to] = depth[v] + 1;
dfs(to, v);
}
}
}
void dfs_down(int v, int p, int k) {
lef_down[v][0] = pos[v];
rig_down[v][0] = pos[v];
for (int to : g[v]) {
if (to != p) {
dfs_down(to, v, k);
for (int j = 1; j <= k; j++) {
lef_down[v][j] = min(lef_down[v][j], lef_down[to][j - 1]);
rig_down[v][j] = max(rig_down[v][j], rig_down[to][j - 1]);
}
}
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
#ifdef LOCAL
freopen("input.txt", "r", stdin);
#endif
int t;
cin >> t;
while (t--) {
int n, k, q;
cin >> n >> k >> q;
init(n, k);
for (int i = 1; i <= n - 1; i++) {
int u, v;;
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
for (int i = 1; i <= q; i++) {
cin >> que[i].first >> que[i].second;
}
dfs(1, 1);
for (int i = 1; i <= n; i++) {
ord[i] = i;
}
sort(ord + 1, ord + n + 1, [&](int i, int j){
return tie(depth[i], i) < tie(depth[j], j);
});
for (int i = 1; i <= n; i++) {
pos[ord[i]] = i;
}
dfs_down(1, 1, k);
for (int ii = 1; ii <= n; ii++) {
int i = ord[ii];
lef_up[i][0] = rig_up[i][0] = pos[i];
for (int j = 1, p = par[i]; j <= k && p != 0; j++, p = par[p]) {
if (j <= k - j) {
lef_down[i][k - 2 * j] = min(lef_down[i][k - 2 * j], lef_down[p][k - j]);
rig_down[i][k - 2 * j] = max(rig_down[i][k - 2 * j], rig_down[p][k - j]);
}
if (j >= k - j) {
lef_up[i][2 * j - k] = min(lef_up[i][2 * j - k], lef_down[p][k - j]);
rig_up[i][2 * j - k] = max(rig_up[i][2 * j - k], rig_down[p][k - j]);
}
}
}
for (int i = 1; i <= q; i++) {
scn[que[i].second].push_back(i);
}
set<Segment> segs;
segs.emplace(1, n, 0);
auto split = [&](int x) { // split [l, r] into [l, x - 1] and [x, r]
if (x == 1 || x == n + 1) {
return;
}
auto it = segs.lower_bound({x + 1, 0, 0});
assert(it != segs.begin());
it--;
assert(it->l <= x && x <= it->r);
if (it->l != x) {
auto cur = *it;
segs.erase(it);
segs.emplace(cur.l, x - 1, cur.val);
segs.emplace(x, cur.r, cur.val);
}
};
auto update = [&](int l, int r, int val) {
if (l > r) return;
split(l);
split(r + 1);
while (true) {
auto it = segs.lower_bound({l, 0, 0});
if (it == segs.end() || it->l >= r + 1) {
break;
} else {
tree.update(it->val, -(it->r - it->l + 1));
segs.erase(it);
}
}
tree.update(val, r - l + 1);
segs.emplace(l, r, val);
};
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= k; j++) {
update(lef_down[i][j], rig_down[i][j], i);
update(lef_up[i][j], rig_up[i][j], i);
}
for (int j : scn[i]) {
ans[j] = tree.get(que[j].first, que[j].second);
}
}
for (int i = 1; i <= q; i++) {
cout << ans[i] << "\n";
}
}
#ifdef LOCAL
cout << "\nTime elapsed: " << double(clock()) / CLOCKS_PER_SEC << " s.\n";
#endif
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 0ms
memory: 16104kb
input:
2 5 1 2 1 2 1 3 2 4 2 5 2 2 2 3 8 2 3 1 2 1 3 2 4 2 5 4 6 5 7 7 8 2 2 2 5 3 4
output:
4 5 6 8 6
result:
wrong answer 3rd numbers differ - expected: '7', found: '6'