QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#445283#8547. Whose Land?ucup-team228WA 0ms16104kbC++205.5kb2024-06-16 00:48:412024-06-16 00:48:41

Judging History

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

  • [2024-06-16 00:48:41]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:16104kb
  • [2024-06-16 00:48:41]
  • 提交

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
}

詳細信息

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'