QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#328271 | #3307. Query on a Tree 17 | aqz180321 | RE | 0ms | 0kb | C++14 | 3.7kb | 2024-02-15 18:47:16 | 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