QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#328271#3307. Query on a Tree 17aqz180321RE 0ms0kbC++143.7kb2024-02-15 18:47:162024-02-15 18:47:16

Judging History

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

  • [2024-02-15 18:47:16]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2024-02-15 18:47:16]
  • 提交

answer

#include <iostream>
#include <cstring>
#include <cstdio>

typedef long long ll;
const ll N = 1e5 + 10;
const ll Q = 1e5 + 10;
struct edge {
    ll to, nxt;
} eg[N << 1];
ll head[N], egtot = 1;
ll n, q;

void add (ll u, ll v) {
    eg[++egtot].to = v;
    eg[egtot].nxt = head[u];
    head[u] = egtot;
}

ll dfntot;
ll son[N], size[N], top[N], dfn[N], fdfn[N], dep[N];
ll st[30][N];

void dfs1 (ll x, ll fa) {
    st[0][x] = fa;
    for (ll i = 1; i <= 20; i++)
        st[i][x] = st[i - 1][st[i - 1][x]];
    dep[x] = dep[fa] + 1;
    size[x] = 1;
    for (ll i = head[x]; i; i = eg[i].nxt) {
        ll to = eg[i].to;
        if (to == fa) continue;
        dfs1(to, x);
        size[x] += size[to];
        if (!son[x] || size[son[x]] < size[to]) son[x] = to;
    }
}

void dfs2 (ll x, ll y) {
    top[x] = y;
    dfn[x] = ++dfntot;
    fdfn[dfntot] = x;
    if (son[x]) dfs2(son[x], y);
    for (ll i = head[x]; i; i = eg[i].nxt) {
        ll to = eg[i].to;
        if (dfn[to]) continue;
        dfs2(to, to);
    }
}

ll sum[N << 2], lazy[N << 2];

void update (ll pos) {
    sum[pos] = sum[pos << 1] + sum[pos << 1 | 1];
}

void push (ll pos, ll l, ll r) {
    if (lazy[pos]) {
        ll mid = (l + r) >> 1;
        sum[pos << 1] = sum[pos << 1] + (mid - l + 1) * lazy[pos];
        sum[pos << 1 | 1] = sum[pos << 1 | 1] + (r - mid) * lazy[pos];
        lazy[pos << 1] = lazy[pos << 1] + lazy[pos];
        lazy[pos << 1 | 1] = lazy[pos << 1 | 1] + lazy[pos];
        lazy[pos] = 0;
    }
}

void modify (ll pos, ll l, ll r, ll x, ll y, ll k) {
    if (x <= l && r <= y) {
        sum[pos] = sum[pos] + (r - l + 1) * k;
        lazy[pos] = lazy[pos] + k;
        return ;
    }
    push(pos, l, r);
    ll mid = (l + r) >> 1;
    if (x <= mid) modify(pos << 1, l, mid, x, y, k);
    if (y >= mid + 1) modify (pos << 1 | 1, mid + 1, r, x, y, k);
    update(pos);
}

ll query1 (ll pos, ll l, ll r, ll x) {
    if (l == r) return fdfn[l];
    push(pos, l, r);
    ll mid = (l + r) >> 1;
    if (sum[pos << 1] >= x) return query1(pos << 1, l, mid, x);
    else return query1(pos << 1 | 1, mid + 1, r, x - sum[pos << 1]);
}

ll query2 (ll pos, ll l, ll r, ll x, ll y) {
    if (x <= l && r <= y) return sum[pos];
    push(pos, l, r);
    ll mid = (l + r) >> 1, ans = 0;
    if (x <= mid) ans += query2(pos << 1, l, mid, x, y);
    if (y >= mid + 1) ans += query2(pos << 1 | 1, mid + 1, r, x, y);
    return ans;
}

int main() {
    scanf("%lld", &n);
    for (ll i = 1, u, v; i < n; i++) {
        scanf("%d%d", &u, &v);
        add(u, v); add(v, u);
    }
    dfs1(1, 0);
    dfs2(1, 1);
    scanf("%lld", &q);
    for (ll i = 1, op, x, y; i <= q; i++) {
        scanf("%lld", &op);
        if (op == 1) {
            scanf("%lld", &x);
            modify(1, 1, n, dfn[x], dfn[x] + size[x] - 1, 1);
        } else {
            scanf("%lld%lld", &x, &y);
            while (top[x] != top[y]) {
                if (dep[top[x]] < dep[top[y]]) std::swap(x, y);
                modify(1, 1, n, dfn[top[x]], dfn[x], 1);
                x = st[0][top[x]];
            }
            if (dfn[x] > dfn[y]) std::swap(x, y);
            modify(1, 1, n, dfn[x], dfn[y], 1);
        }
        ll tmp = sum[1] / 2 + 1;
        ll p = query1(1, 1, n, tmp);
        if (query2(1, 1, n, dfn[p], dfn[p] + size[p] - 1) >= tmp) printf("%lld\n", p);
        else {
            for (ll i = 20; i >= 0; i--) {
                ll x = st[i][p];
                if (!x) continue;
                if (query2(1, 1, n, dfn[x], dfn[x] + size[x] - 1) < tmp) p = x;
            }
            printf("%lld\n", st[0][p]);
        }
    }
    return 0;
}

详细

Test #1:

score: 0
Runtime Error

input:

7
1 6
1 7
7 3
3 2
7 5
5 4
4
1 2
1 4
1 6
2 6 7

output:


result: