QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#473531 | #1163. Another Tree Queries Problem | aqz180321 | WA | 83ms | 46412kb | C++14 | 5.8kb | 2024-07-12 08:36:56 | 2024-07-12 08:36:57 |
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), -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;
}
详细
Test #1:
score: 100
Accepted
time: 3ms
memory: 43492kb
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: 83ms
memory: 46412kb
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 8869 9321 14800 13562 13795 12820 8971 11437 12045 13368 12368 12663 15864 16562 19816 17893 12942 16096 12849 16412 12951 18846 18352 23962 18726 26222 15503 251...
result:
wrong answer 1st numbers differ - expected: '826', found: '494'