QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#473528 | #1163. Another Tree Queries Problem | aqz180321 | WA | 87ms | 45356kb | C++14 | 5.8kb | 2024-07-12 08:32:41 | 2024-07-12 08:32:41 |
Judging History
answer
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
const int N = 2e5 + 10;
int n, q;
std::vector < int > edge[N];
int dfn[N], dfntot, id[N];
int dep[N], son[N], size[N], fa[N], top[N], st[30][N];
struct seg1 {
int sum[N << 2], lazya[N << 2], lazyb[N << 2];
void add (int pos, int l, int r, int a, int b) {
sum[pos] += (l + r) * a * (r - l + 1) / 2;
sum[pos] += (r - l + 1) * b;
lazya[pos] += a;
lazyb[pos] += b;
}
void update (int pos) {
sum[pos] = sum[pos << 1] + sum[pos << 1 | 1];
}
void push (int pos, int l, int r) {
if (lazya[pos] || lazyb[pos]) {
int mid = (l + r) >> 1;
add (pos << 1, l, mid, lazya[pos], lazyb[pos]);
add (pos << 1 | 1, mid + 1, r, lazya[pos], lazyb[pos]);
lazya[pos] = lazyb[pos] = 0;
}
}
void build (int pos, int l, int r) {
sum[pos] = lazya[pos] = lazyb[pos] = 0;
if (l == r) return ;
int mid = (l + r) >> 1;
build (pos << 1, l, mid);
build (pos << 1 | 1, mid + 1, r);
}
void modify (int pos, int l, int r, int x, int y, int a, int b) {
if (x <= l && r <= y) {
add (pos, l, r, a, b);
return ;
}
push (pos, l, r);
int mid = (l + r) >> 1;
if (x <= mid) modify (pos << 1, l, mid, x, y, a, b);
if (y >= mid + 1) modify (pos << 1 | 1, mid + 1, r, x, y, a, b);
update (pos);
}
int query (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 += query (pos << 1, l, mid, x, y);
if (y >= mid + 1) ans += query (pos << 1 | 1, mid + 1, r, x, y);
return ans;
}
} tr1;
struct seg2 {
int sz[N << 2], sum[N << 2];
int lazy[N << 2];
void add (int pos, int k) {
sum[pos] += sz[pos] * k;
lazy[pos] += k;
}
void push (int pos) {
if (lazy[pos]) {
add (pos << 1, lazy[pos]);
add (pos << 1 | 1, lazy[pos]);
lazy[pos] = 0;
}
}
void update (int pos) {
sz[pos] = sz[pos << 1] + sz[pos << 1 | 1];
sum[pos] = sum[pos << 1] + sum[pos << 1 | 1];
}
void build (int pos, int l, int r) {
sum[pos] = lazy[pos] = 0;
if (l == r) {
sz[pos] = size[id[l]];
return ;
}
int mid = (l + r) >> 1;
build (pos << 1, l, mid);
build (pos << 1 | 1, mid + 1, r);
update (pos);
}
void modify (int pos, int l, int r, int x, int y, int k) {
if (x <= l && r <= y) {
add (pos, k);
return ;
}
push (pos);
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 query (int pos, int l, int r, int x, int y) {
if (x <= l && r <= y) return sum[pos];
push (pos);
int mid = (l + r) >> 1, ans = 0;
if (x <= mid) ans += query (pos << 1, l, mid, x, y);
if (y >= mid + 1) ans += query (pos << 1 | 1, mid + 1, r, x, y);
return ans;
}
} tr2;
void dfs1 (int x, int father) {
fa[x] = father;
st[0][x] = father;
dep[x] = dep[father] + 1;
size[x] = 1;
for (int i = 1; i <= 25; i++)
st[i][x] = st[i - 1][st[i - 1][x]];
for (auto v : edge[x]) {
if (v == father) continue;
dfs1 (v, x);
size[x] += size[v];
if (size[son[x]] < size[v]) son[x] = v;
}
}
void dfs2 (int x, int y) {
top[x] = y;
dfn[x] = ++dfntot;
id[dfntot] = x;
if (son[x]) dfs2 (son[x], y);
for (auto v : edge[x]) {
if (dfn[v]) continue;
dfs2 (v, v);
}
}
int lca (int x, int y) {
if (dep[x] < dep[y]) std::swap(x, y);
int k = dep[x] - dep[y];
for (int j = 0; k; j++, k >>= 1)
if (k & 1) x = st[j][x];
if (x == y) return x;
for (int i = 20; i >= 0; i--)
if (st[i][x] != st[i][y]) {
x = st[i][x];
y = st[i][y];
}
return st[0][x];
}
int depsum[N], asum, adepsum;
void rootupd (int u, int cnt) {
asum += cnt;
while (u != 0) {
tr1.modify (1, 1, n, dfn[top[u]], dfn[u], 0, cnt);
u = fa[top[u]];
}
return ;
}
void subtree (int u, int k) {
adepsum += k * (depsum[dfn[u] + size[u] - 1] - depsum[dfn[u] - 1]);
tr2.modify (1, 1, n, dfn[u], dfn[u] + size[u] - 1, k);
rootupd (fa[u], k * size[u]);
}
int jump (int u, int k) {
for (int j = 0; k; k >>= 1, j++)
if (k & 1) u = st[j][u];
return u;
}
void work1 (int u, int v) {
if (u == v) {
subtree(1, 1);
return ;
}
int k = lca(u, v);
if (k == v) subtree(1, 1), subtree(jump(u, dep[u] - dep[v]), -1);
else subtree(v, 1);
}
void work2 (int u, int v) {
int lfs = 0, ris = 0;
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]])
std::swap(u, v), std::swap(lfs, ris);
tr1.modify (1, 1, n, dfn[top[u]], dfn[u], -1, dfn[u] + 1 + lfs);
lfs += dfn[top[u]] - dfn[u] + 1;
adepsum += (depsum[dfn[u]] - depsum[dfn[top[u]] - 1]);
u = fa[top[u]];
}
if (dfn[u] < dfn[v])
std::swap(u, v), std::swap(lfs, ris);
adepsum += (depsum[dfn[u]] - depsum[dfn[v] - 1]);
tr1.modify (1, 1, n, dfn[v], dfn[u], -1, dfn[u] + 1 + lfs);
tr1.modify (1, 1, n, dfn[v], dfn[v], 0, ris);
rootupd (fa[v], lfs + ris + dep[u] - dep[v] + 1) ;
}
int getsum (int u) {
int ans = adepsum;
while (u != 0) {
ans = ans - 2 * (tr1.query (1, 1, n, dfn[top[u]], dfn[u]) + tr2.query (1, 1, n, dfn[top[u]], dfn[u]));
ans = ans + (dfn[u] - dfn[top[u]] + 1) * asum;
u = fa[top[u]];
}
return ans;
}
int main() {
scanf("%d", &n);
for (int i = 1, u, v; i < n; i++) {
scanf("%d%d", &u, &v);
edge[u].push_back(v);
edge[v].push_back(u);
}
dfs1 (1, 0);
dfs2 (1, 1);
for (int i = 1; i <= n; i++)
depsum[i] = depsum[i - 1] + dep[id[i]];
tr1.build (1, 1, n);
tr2.build (1, 1, n);
scanf("%d", &q);
for (int i = 1, opt, u, v; i <= q; i++) {
scanf("%d", &opt);
if (opt == 1) {
scanf("%d%d", &u, &v);
work1 (u, v);
} else if (opt == 2) {
scanf("%d%d", &u, &v);
work2 (u, v);
} else if (opt == 3) {
scanf("%d", &u);
printf("%d\n", getsum(u));
}
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 45356kb
input:
5 4 2 2 5 1 5 1 3 5 2 2 4 3 4 2 1 5 2 5 5 3 2
output:
1 5
result:
ok 2 number(s): "1 5"
Test #2:
score: -100
Wrong Answer
time: 87ms
memory: 43516kb
input:
200 171 114 50 183 28 68 67 152 139 125 67 55 50 98 106 71 46 42 157 165 42 49 113 12 81 145 105 13 38 96 34 156 24 17 21 191 135 54 174 116 177 157 123 71 95 130 135 193 150 129 25 190 96 93 188 173 90 160 86 187 20 132 199 75 59 195 189 24 40 68 163 83 25 13 73 33 59 50 154 19 146 21 151 67 89 69 ...
output:
494 400 457 1385 1884 1416 2226 2203 3871 3325 3117 3185 3939 3259 3976 5911 4662 4305 6051 7241 5053 5604 5672 4470 9919 10695 7937 8199 8817 9273 14712 13462 13719 12816 8919 11413 11985 13362 12308 12550 15716 16464 19693 17802 12887 15969 12793 16320 12887 18792 18270 23839 18644 26089 15449 250...
result:
wrong answer 1st numbers differ - expected: '826', found: '494'