QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#578729#8547. Whose Land?ucup-team4435WA 307ms3756kbC++206.1kb2024-09-20 21:01:562024-09-20 21:01:56

Judging History

你现在查看的是最新测评结果

  • [2024-09-20 21:01:56]
  • 评测
  • 测评结果:WA
  • 用时:307ms
  • 内存:3756kb
  • [2024-09-20 21:01:56]
  • 提交

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);
    }
}

Details

Tip: Click on the bar to expand more detailed information

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'