QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#328246 | #3307. Query on a Tree 17 | aqz180321 | RE | 0ms | 16140kb | C++14 | 3.7kb | 2024-02-15 18:31:52 | 2024-02-15 18:31:52 |
Judging History
answer
#include <iostream>
#include <cstring>
#include <cstdio>
const int N = 1e5 + 10;
const int Q = 1e5 + 10;
struct edge {
int to, nxt;
} eg[N << 1];
int head[N], egtot = 1;
int n, q;
void add (int u, int v) {
eg[++egtot].to = v;
eg[egtot].nxt = head[u];
head[u] = egtot;
}
int dfntot;
int son[N], size[N], top[N], dfn[N], fdfn[N], dep[N];
int st[30][N];
void dfs1 (int x, int fa) {
st[0][x] = fa;
for (int i = 1; i <= 20; i++)
st[i][x] = st[i - 1][st[i - 1][x]];
dep[x] = dep[fa] + 1;
size[x] = 1;
for (int i = head[x]; i; i = eg[i].nxt) {
int 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 (int x, int y) {
top[x] = y;
dfn[x] = ++dfntot;
fdfn[dfntot] = x;
if (son[x]) dfs2(son[x], y);
for (int i = head[x]; i; i = eg[i].nxt) {
int to = eg[i].to;
if (dfn[to]) continue;
dfs2(to, to);
}
}
int sum[N << 2], lazy[N << 2];
void update (int pos) {
sum[pos] = sum[pos << 1] + sum[pos << 1 | 1];
}
void push (int pos, int l, int r) {
if (lazy[pos]) {
int 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 (int pos, int l, int r, int x, int y, int k) {
if (x <= l && r <= y) {
sum[pos] = sum[pos] + (y - x + 1) * k;
lazy[pos] = lazy[pos] + k;
return ;
}
push(pos, l, r);
int 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);
}
int query1 (int pos, int l, int r, int x) {
if (l == r) return fdfn[l];
push(pos, l, r);
int 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]);
}
int query2 (int pos, int l, int r, int x, int y) {
if (x <= l && r <= y) return sum[pos];
push(pos, l, r);
int 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("%d", &n);
for (int 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("%d", &q);
for (int i = 1, op, x, y; i <= q; i++) {
scanf("%d", &op);
if (op == 1) {
scanf("%d", &x);
modify(1, 1, n, dfn[x], dfn[x] + size[x] - 1, 1);
} else {
scanf("%d%d", &x, &y);
while (top[x] != top[y]) {
if (dep[x] < dep[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);
}
int tmp = sum[1] / 2 + 1;
int p = query1(1, 1, n, tmp);
if (query2(1, 1, n, dfn[p], dfn[p] + size[p] - 1) >= tmp) printf("%d\n", p);
else {
for (int i = 20; i >= 0; i--) {
int x = st[i][p];
if (!x) continue;
if (query2(1, 1, n, dfn[x], dfn[x] + size[x] - 1) < tmp) p = x;
}
printf("%d\n", st[0][p]);
}
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 16140kb
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:
2 7 7 1
result:
ok 4 lines
Test #2:
score: -100
Runtime Error
input:
15 1 2 1 3 2 4 3 7 6 2 3 8 4 9 2 5 5 11 7 13 10 4 11 15 12 5 14 7 11 2 6 11 1 6 2 10 9 1 9 2 2 6 1 4 2 7 6 1 2 2 8 13 1 10 2 8 15