QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#327618 | #3307. Query on a Tree 17 | JWRuixi | WA | 1ms | 6052kb | C++20 | 3.7kb | 2024-02-15 11:30:28 | 2024-02-15 11:30:28 |
Judging History
answer
#include <bits/stdc++.h>
#define IL inline
#define LL long long
#define eb emplace_back
#define L(i, j, k) for (int i = (j); i <= (k); ++i)
#define R(i, j, k) for (int i = (j); i >= (k); --i)
using namespace std;
namespace IO {
char ibuf[1 << 20], *iS, *iT;
#ifndef LOCAL
#define gh() (iS == iT ? iT = (iS = ibuf) + fread(ibuf, 1, 1 << 20, stdin), (iS == iT ? EOF : *iS++) : *iS++)
#else
#define gh() getchar()
#endif
template<typename T = int>
IL T read () {
T x = 0;
bool f = 0;
char c = gh();
while (c < '0' || '9' < c) f |= c == '-', c = gh();
while ('0' <= c && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = gh();
return f ? ~(x - 1) : x;
}
}
using IO::read;
using ci = const int;
using vi = vector<int>;
constexpr int N = 1e5 + 9;
constexpr int M = 20;
int n, m, dep[N], sz[N], son[N], top[N], dfn[N], id[N], dfc, par[N], st[N][M];
vi g[N];
namespace SGT {
LL tr[N << 2], tg[N << 2];
#define ls (p << 1)
#define rs (p << 1 | 1)
IL void pushup (int p) {
tr[p] = tr[ls] + tr[rs];
}
IL void push (int p, int v) {
tr[p] += v;
tg[p] += v;
}
IL void pushdown (int p) {
auto &o = tg[p];
if (o) {
push(ls, o);
push(rs, o);
o = 0;
}
}
IL void upd (int ql, int qr, int l, int r, int p) {
if (ql <= l && r <= qr) {
push(p, 1);
return;
}
pushdown(p);
ci mid = (l + r) >> 1;
if (ql <= mid) upd(ql, qr, l, mid, ls);
if (mid < qr) upd(ql, qr, mid + 1, r, rs);
pushup(p);
}
IL void upd (int l, int r) {
upd(l, r, 1, n, 1);
}
IL LL qry (int ql, int qr, int l, int r, int p) {
if (ql <= l && r <= qr) {
return tr[p];
}
pushdown(p);
ci mid = (l + r) >> 1;
LL R = 0;
if (ql <= mid) R += qry(ql, qr, l, mid, ls);
if (mid < qr) R += qry(ql, qr, mid + 1, r, rs);
return R;
}
IL LL qry (int l, int r) {
return qry(l, r, 1, n, 1);
}
}
IL void dfs1 (int u, int fa) {
sz[u] = 1;
par[u] = fa;
dep[u] = dep[fa] + 1;
for (int v : g[u]) {
if (v == fa) continue;
dfs1(v, u);
sz[u] += sz[v];
if (sz[v] > sz[son[u]]) son[u] = v;
}
}
IL void dfs2 (int u, int tp) {
top[u] = tp;
id[dfn[u] = ++dfc] = u;
if (son[u]) {
dfs2(son[u], tp);
}
for (int v : g[u]) {
if (v == son[u] || v == par[u]) continue;
dfs2(v, v);
}
}
void init () {
dfs1(1, 0);
dfs2(1, 1);
L (i, 1, n) {
int k = id[i];
st[k][0] = par[k];
L (j, 1, 17) st[k][j] = st[st[k][j - 1]][j - 1];
}
}
IL LL siz (int u) {
return SGT::qry(dfn[u], dfn[u] + sz[u] - 1);
}
int main () {
n = read();
L (i, 1, n - 1) {
int u = read(), v = read();
g[u].eb(v);
g[v].eb(u);
}
init();
m = read();
LL all = 0;
while (m--) {
int o = read();
if (o == 1) {
int x = read();
SGT::upd(dfn[x], dfn[x] + sz[x] - 1);
all += sz[x];
} else {
int x = read(), y = read();
all += dep[x] + dep[y] + 1;
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
SGT::upd(dfn[top[x]], dfn[x]);
x = par[top[x]];
}
if (dep[x] < dep[y]) swap(x, y);
SGT::upd(dep[y], dfn[x]);
all -= 2 * dep[y];
}
int l = 1, r = n, md, p = 0;
while (l <= r) {
md = (l + r) >> 1;
SGT::qry(1, md) * 2 >= all ? p = md, r = md - 1 : l = md + 1;
}
p = id[p];
if (siz(p) * 2 > all) {
printf("%d\n", p);
continue;
}
R (i, 17, 0) {
int q = st[p][i];
if (q && siz(q) * 2 <= all) {
p = st[p][i];
}
}
printf("%d\n", par[p]);
}
}
// I love WHQ!
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 5984kb
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: 0
Accepted
time: 0ms
memory: 6052kb
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
output:
2 2 2 2 2 2 2 2 2 2 2
result:
ok 11 lines
Test #3:
score: -100
Wrong Answer
time: 1ms
memory: 5812kb
input:
2 1 2 1 1 1
output:
0
result:
wrong answer 1st lines differ - expected: '1', found: '0'