QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#578729 | #8547. Whose Land? | ucup-team4435 | WA | 307ms | 3756kb | C++20 | 6.1kb | 2024-09-20 21:01:56 | 2024-09-20 21:01:56 |
Judging History
answer
#include <bits/stdc++.h>
/*
* Zero based.
* Don't forget to run .build(root) method before using it.
*/
class tree_bfs_ordering {
private:
int n, timer;
std::vector<int> depth_left;
void dfs(int v) {
tin[v] = timer++;
for (auto u : g[v]) {
if (u == parent[v]) {
continue;
}
parent[u] = v;
dfs(u);
}
tout[v] = timer;
}
void bfs(int root) {
depth.assign(n, -1);
order = {root};
order.reserve(n);
depth[root] = 0;
for (int ptr = 0; ptr < n; ptr++) {
int v = order[ptr];
for (int u : g[v]) {
if (depth[u] == -1) {
depth[u] = depth[v] + 1;
order.push_back(u);
}
}
}
int max_depth = depth[order.back()];
depth_left.assign(max_depth + 2, 0);
for (int v = 0; v < n; v++) {
depth_left[depth[v] + 1]++;
}
for (int d = 0; d <= max_depth; d++) {
depth_left[d + 1] += depth_left[d];
}
}
int search(int range_depth, int t) {
int left = depth_left[range_depth];
int right = depth_left[range_depth + 1];
return std::partition_point(order.begin() + left, order.begin() + right, [&](int i) {
return tin[order[i]] < t;
}) - order.begin();
}
public:
std::vector<std::vector<int>> g;
std::vector<int> tin, tout, depth, parent, order;
tree_bfs_ordering(int n = 0) : n(n), g(n) {}
void add(int v, int u) {
g[v].push_back(u);
g[u].push_back(v);
}
int size() const {
return n;
}
void build(int root) {
timer = 0;
tin.resize(n);
tout.resize(n);
parent.assign(n, -1);
dfs(root);
bfs(root);
}
// Returns true if v == u or v is ancestor of u.
bool is_ancestor(int v, int u) const {
return tin[v] <= tin[u] && tout[u] <= tout[v];
}
/*
* Returns interval [l, r), such that order[l : r] contains verteces
from the subtree of vertex 'v' at the distance of 'dist' from vertex 'v'.
* If there's no such verteces, returns [0, 0).
* Complexity: O(log(n)).
*/
std::pair<int, int> range(int v, int dist) {
int range_depth = depth[v] + dist;
if (range_depth + 1 >= static_cast<int>(depth_left.size())) {
return {0, 0};
}
return {search(range_depth, tin[v]), search(range_depth, tout[v])};
}
/*
* Returns set of at most 2 * dist + 1 disjoint ranges, containing all verteces at the distance of at most 'dist'.
* Complexity: O(dist * log(n)).
*/
std::vector<std::pair<int, int>> ranges(int v, int dist) {
std::vector<std::pair<int, int>> ranges;
ranges.reserve(2 * dist + 1);
int p = v;
for (int d = depth[v] + dist; d >= std::max(0, depth[v] - dist); d--) {
if (parent[p] != -1 && depth[v] + d - 2 * depth[parent[p]] <= dist) {
p = parent[p];
}
auto [l, r] = range(p, d - depth[p]);
if (l < r) {
ranges.emplace_back(l, r);
}
}
return ranges;
}
};
/*
* Zero based.
* Type T must have operator += T.
* Type T must have default constructor, which sets neutral value.
* Operation += must be commutative.
* For segment query type T must have operator -= T.
*/
template<typename T>
struct binary_indexed_tree {
std::vector<T> bit;
// Fills the array with default values.
binary_indexed_tree(int n = 0) : bit(n + 1) {}
int size() const {
return int(bit.size()) - 1;
}
// Adds delta at the position pos.
void add(int pos, T delta) {
for (pos++; pos < static_cast<int>(bit.size()); pos += pos & -pos) {
bit[pos] += delta;
}
}
// Returns the sum on the segment [0, pref].
T query(int pref) {
T sum = T();
for (pref++; pref > 0; pref -= pref & -pref) {
sum += bit[pref];
}
return sum;
}
// Returns the sum on the interval [l, r).
T query(int l, int r) {
if (r <= l) {
return T();
}
T res = query(r - 1);
res -= query(l - 1);
return res;
}
};
using namespace std;
void solve(int /* test_num */) {
int n, k, q;
cin >> n >> k >> q;
tree_bfs_ordering tree(n);
for (int i = 1, v, u; i < n; i++) {
cin >> v >> u;
v--, u--;
tree.add(v, u);
}
tree.build(0);
vector<vector<pair<int, int>>> queries(n);
vector<int> ans(q);
for (int i = 0; i < q; i++) {
int l, r;
cin >> l >> r;
l--, r--;
queries[r].emplace_back(l, i);
}
binary_indexed_tree<int> bit(n);
set<array<int, 3>> segs;
segs.insert({0, n, -1});
auto update = [&](int l, int r, int val) {
bit.add(val, r - l);
int init_l = l;
while (l < r) {
auto it = prev(segs.lower_bound({l + 1, -1, -1}));
auto [lx, rx, val] = *it;
segs.erase(it);
if (val != -1) {
bit.add(val, max(l, lx) - min(r, rx));
}
if (lx < l) {
segs.insert({lx, l, val});
}
if (r < rx) {
segs.insert({r, rx, val});
}
l = rx;
}
segs.insert({init_l, r, val});
};
for (int r = 0; r < n; r++) {
for (auto [lx, rx] : tree.ranges(r, k)) {
update(lx, rx, r);
}
for (auto [l, qid] : queries[r]) {
ans[qid] = bit.query(l, r + 1);
}
}
for (auto x : ans) {
cout << x << '\n';
}
}
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int tests;
cin >> tests;
for (int test_num = 1; test_num <= tests; test_num++) {
solve(test_num);
}
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 3624kb
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 7 8 6
result:
ok 5 number(s): "4 5 7 8 6"
Test #2:
score: -100
Wrong Answer
time: 307ms
memory: 3756kb
input:
1000 500 1 500 291 2 406 9 207 13 71 15 351 17 442 18 496 19 104 20 208 23 448 34 80 42 187 44 352 45 290 46 116 47 318 50 226 52 129 55 83 59 100 60 54 61 73 65 63 66 454 67 43 71 26 74 68 26 320 75 388 76 425 79 170 81 350 83 48 85 153 86 221 90 290 95 130 96 82 98 124 82 36 99 213 100 121 101 132...
output:
155 228 211 102 170 198 232 16 195 232 228 198 105 121 226 260 98 37 201 182 52 199 24 205 162 28 101 251 71 14 133 251 202 175 139 218 251 258 41 207 35 234 227 129 228 155 113 146 65 39 109 231 231 200 209 258 179 129 205 230 132 252 93 127 260 53 252 106 165 145 178 226 62 242 252 191 70 130 108 ...
result:
wrong answer 1st numbers differ - expected: '255', found: '155'