QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#443728 | #8647. JOI Tour | Qwerty1232# | 0 | 933ms | 288092kb | C++23 | 8.0kb | 2024-06-15 16:23:00 | 2024-06-15 16:23:02 |
Judging History
answer
#include <bits/stdc++.h>
#include "joitour.h"
struct ST {
std::vector<int> data;
int size;
ST() = default;
ST(int n) {
size = 1 << std::__lg(std::max<int>(1, n - 1)) + 1;
data.assign(size * 2, 0);
}
void add_point(int i, int dlt) {
for (i += size; i > 0; i >>= 1) {
data[i] += dlt;
}
}
int get_sum_range(int l, int r) {
int sum = 0;
for (l += size, r += size; l < r; l >>= 1, r >>= 1) {
if (l & 1)
sum += data[l++];
if (r & 1)
sum += data[--r];
}
return sum;
}
int get_sum_point(int i) {
int sum = 0;
for (i += size; i > 0; i >>= 1) {
sum += data[i];
}
return sum;
}
void add_range(int l, int r, int dlt) {
for (l += size, r += size; l < r; l >>= 1, r >>= 1) {
if (l & 1)
data[l++] += dlt;
if (r & 1)
data[--r] += dlt;
}
}
};
int n;
std::vector<int> input;
std::vector<std::vector<int>> gr;
std::vector<bool> used;
std::vector<int> sz;
std::vector<int> depth, prv, ctr_deg;
struct Cum {
int a, c;
int64_t bc, ba;
Cum operator-(const Cum& other) const {
return Cum{a - other.a, c - other.c, bc - other.bc, ba - other.ba};
}
Cum operator+(const Cum& other) const {
return Cum{a + other.a, c + other.c, bc + other.bc, ba + other.ba};
}
};
std::vector<std::vector<Cum>> count;
struct Fuck {
int64_t ans_a, ans_b, ans_c;
Fuck operator-(const Fuck& other) const {
return Fuck{ans_a - other.ans_a, ans_b - other.ans_b, ans_c - other.ans_c};
}
Fuck operator+(const Fuck& other) const {
return Fuck{ans_a + other.ans_a, ans_b + other.ans_b, ans_c + other.ans_c};
}
int64_t get(int i) const {
return i == 0 ? ans_a : (i == 1 ? ans_b : ans_c);
}
};
std::vector<Fuck> fuck_ans;
std::vector<std::vector<int>> dist, tin, tout, eul, subtree_num;
std::vector<ST> st_a, st_b, st_c;
Fuck get_ans(Cum val, Cum /* without val */ total) {
int64_t cum = 0;
cum += val.a * total.bc;
cum += val.c * total.ba;
cum += val.ba * total.c;
cum += val.bc * total.a;
Fuck res{cum, cum, cum};
res.ans_a = val.bc;
res.ans_b += val.a * int64_t(total.c) + val.c * int64_t(total.a);
res.ans_c = val.ba;
return res;
}
int64_t ans;
void init(int N, std::vector<int> F, std::vector<int> U, std::vector<int> V, int Q) {
n = N;
input = F;
gr.assign(n, {});
for (int i = 0; i < n - 1; i++) {
gr[U[i]].push_back(V[i]);
gr[V[i]].push_back(U[i]);
}
ans = 0;
sz.assign(n, 0), used.assign(n, false), depth.assign(n, -1), prv.assign(n, -1), ctr_deg.assign(n, -1);
count.assign(n, {}), fuck_ans.assign(n, Fuck());
dist.clear(), tin.clear(), tout.clear(), subtree_num.clear(), eul.assign(n, {});
st_a.assign(n, {}), st_b.assign(n, {}), st_c.assign(n, {});
auto find = [&](int v) {
auto dfs = [&](auto dfs, int v, int f) -> void {
sz[v] = 1;
for (int t : gr[v]) {
if (t != f && !used[t]) {
dfs(dfs, t, v);
sz[v] += sz[t];
}
}
};
dfs(dfs, v, -1);
int f = -1;
int s = sz[v];
while (true) {
auto it = std::find_if(gr[v].begin(), gr[v].end(), [&](int t) { return t != f && !used[t] && sz[t] > s / 2; });
if (it != gr[v].end()) {
f = v;
v = *it;
} else {
break;
}
}
return v;
};
auto build = [&](auto build, int u, int dp, int f) -> void {
u = find(u);
used[u] = true;
depth[u] = dp;
prv[u] = f;
if (dist.size() == dp) {
dist.emplace_back(n, -1);
tin.emplace_back(n, -1);
tout.emplace_back(n, -1);
subtree_num.emplace_back(n, -2);
}
auto dfs = [&](auto dfs, int v, int f, int sn) -> int {
tin[dp][v] = eul[u].size();
eul[u].push_back(v);
subtree_num[dp][v] = sn;
int cnt = 0;
for (int t : gr[v]) {
if (t != f && !used[t]) {
dfs(dfs, t, v, f == -1 ? cnt : sn);
cnt++;
}
}
tout[dp][v] = eul[u].size();
return cnt;
};
int g = ctr_deg[u] = dfs(dfs, u, -1, -1);
count[u].assign(g + 1, Cum());
int m = eul[u].size();
st_a[u] = ST(m), st_b[u] = ST(m), st_c[u] = ST(m);
for (int i = 1; i < m; i++) {
int v = eul[u][i];
int sb = subtree_num[dp][v];
if (input[v] == 0) {
count[u][sb].a += 1;
count[u][sb].ba += st_b[u].get_sum_point(tin[dp][v]);
st_a[u].add_point(tin[dp][v], +1);
} else if (input[v] == 2) {
count[u][sb].c += 1;
count[u][sb].bc += st_b[u].get_sum_point(tin[dp][v]);
st_c[u].add_point(tin[dp][v], +1);
} else {
count[u][sb].ba += st_a[u].get_sum_range(tin[dp][v], tout[dp][v]);
count[u][sb].bc += st_c[u].get_sum_range(tin[dp][v], tout[dp][v]);
st_b[u].add_range(tin[dp][v], tout[dp][v], +1);
}
}
fuck_ans[u] = Fuck();
for (int i = 0; i < g; i++) {
fuck_ans[u] = fuck_ans[u] + get_ans(count[u][i], count[u][g]);
count[u][g] = count[u][g] + count[u][i];
}
ans += fuck_ans[u].get(input[u]);
for (int t : gr[u]) {
if (!used[t]) {
build(build, t, dp + 1, u);
}
}
};
build(build, 0, 0, -1);
}
void change(int v, int y) {
int y0 = input[v];
int u = v;
while (u != -1) {
int dp = depth[u];
int sb = subtree_num[dp][v];
input[v] = y0;
ans -= fuck_ans[u].get(input[u]);
if (sb != -1) {
count[u][ctr_deg[u]] = count[u][ctr_deg[u]] - count[u][sb];
fuck_ans[u] = fuck_ans[u] - get_ans(count[u][sb], count[u][ctr_deg[u]]);
if (input[v] == 0) {
count[u][sb].a -= 1;
count[u][sb].ba -= st_b[u].get_sum_point(tin[dp][v]);
st_a[u].add_point(tin[dp][v], -1);
} else if (input[v] == 2) {
count[u][sb].c -= 1;
count[u][sb].bc -= st_b[u].get_sum_point(tin[dp][v]);
st_c[u].add_point(tin[dp][v], -1);
} else {
count[u][sb].ba -= st_a[u].get_sum_range(tin[dp][v], tout[dp][v]);
count[u][sb].bc -= st_c[u].get_sum_range(tin[dp][v], tout[dp][v]);
st_b[u].add_range(tin[dp][v], tout[dp][v], -1);
}
}
input[v] = y;
if (sb != -1) {
if (input[v] == 0) {
count[u][sb].a += 1;
count[u][sb].ba += st_b[u].get_sum_point(tin[dp][v]);
st_a[u].add_point(tin[dp][v], +1);
} else if (input[v] == 2) {
count[u][sb].c += 1;
count[u][sb].bc += st_b[u].get_sum_point(tin[dp][v]);
st_c[u].add_point(tin[dp][v], +1);
} else {
count[u][sb].ba += st_a[u].get_sum_range(tin[dp][v], tout[dp][v]);
count[u][sb].bc += st_c[u].get_sum_range(tin[dp][v], tout[dp][v]);
st_b[u].add_range(tin[dp][v], tout[dp][v], +1);
}
fuck_ans[u] = fuck_ans[u] + get_ans(count[u][sb], count[u][ctr_deg[u]]);
count[u][ctr_deg[u]] = count[u][ctr_deg[u]] + count[u][sb];
}
ans += fuck_ans[u].get(input[u]);
u = prv[u];
}
}
long long num_tours() {
// return 0;
return ans;
}
詳細信息
Subtask #1:
score: 0
Wrong Answer
Test #1:
score: 0
Wrong Answer
time: 0ms
memory: 4156kb
input:
400 1 1 0 2 2 0 2 1 1 1 1 0 1 2 2 2 2 0 0 2 0 2 0 2 1 1 2 2 1 2 1 0 1 2 2 2 0 0 0 2 1 2 2 0 0 0 1 2 1 1 0 1 1 2 1 2 2 2 1 1 0 1 1 1 2 2 1 1 0 0 1 1 0 0 1 1 1 2 2 2 1 1 2 1 1 1 0 2 0 2 1 0 1 1 2 0 0 2 1 0 2 2 1 0 0 0 0 1 1 1 0 1 2 1 1 1 2 0 2 2 0 2 0 1 0 1 1 1 1 0 1 1 0 0 0 2 2 0 2 2 2 1 1 0 1 2 0 1 ...
output:
563649 570062 569955 566251 563771 560759 559959 552598 548889 548294 553439 554055 557441 558202 555300 553535 556706 560852 557694 557346 559538 557987 553299 548983 548146 546689 543248 544487 545678 544438 544320 543501 543985 550152 557483 560103 556510 555658 549165 548338 546924 552006 553998...
result:
wrong answer
Subtask #2:
score: 0
Skipped
Dependency #1:
0%
Subtask #3:
score: 0
Wrong Answer
Test #11:
score: 0
Wrong Answer
time: 933ms
memory: 288092kb
input:
200000 0 2 2 0 2 2 0 1 1 0 2 2 0 1 2 2 0 1 0 2 1 1 0 1 0 2 0 2 0 0 0 1 0 0 2 0 2 1 0 0 1 1 1 0 0 2 1 2 2 1 0 2 2 2 0 2 2 1 2 0 1 0 0 1 2 0 0 2 1 1 1 0 1 1 1 2 1 0 1 1 0 1 2 2 2 0 1 0 1 1 0 2 0 1 0 2 0 0 2 2 2 2 2 0 0 2 1 2 2 1 2 0 1 1 1 1 1 0 2 0 2 0 1 1 1 0 1 0 2 1 2 0 1 1 0 2 1 2 2 2 0 0 2 2 2 0 1...
output:
3995094643048
result:
wrong answer
Subtask #4:
score: 0
Wrong Answer
Test #38:
score: 16
Accepted
time: 0ms
memory: 3792kb
input:
3 1 1 1 0 1 1 2 100 2 0 0 0 0 2 2 1 0 1 0 0 0 1 0 0 1 0 2 2 0 1 0 0 0 1 1 1 0 0 2 0 2 1 2 2 0 2 2 1 2 2 2 0 0 1 2 1 0 2 0 1 2 0 2 1 0 0 2 0 2 1 2 2 0 2 2 0 0 0 2 1 2 0 2 2 1 2 0 1 1 1 2 1 0 0 0 2 0 1 0 0 1 2 1 0 1 2 1 0 0 1 2 2 2 1 2 2 0 2 1 2 2 1 0 0 0 2 0 1 1 1 2 0 0 0 1 2 0 2 0 0 1 0 0 1 0 2 2 1 ...
output:
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0
result:
ok
Test #39:
score: -16
Wrong Answer
time: 1ms
memory: 3868kb
input:
4 2 2 2 0 0 1 1 2 2 3 100 0 0 3 2 1 1 3 1 0 2 2 0 1 0 3 0 0 1 1 2 0 0 3 2 3 1 1 0 3 2 3 0 3 1 1 2 3 2 0 1 2 2 2 1 1 0 1 1 1 0 3 0 0 2 1 2 0 0 3 1 1 0 2 0 3 0 2 2 3 2 0 2 0 1 3 1 2 1 3 0 1 2 2 2 3 2 2 1 1 1 3 1 1 2 2 0 0 2 1 1 0 1 3 0 2 2 0 2 0 0 1 0 3 1 2 1 0 2 2 2 0 0 0 1 3 0 2 1 1 2 3 1 3 2 1 1 2 ...
output:
0 0 0 2 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
result:
wrong answer
Subtask #5:
score: 0
Wrong Answer
Test #60:
score: 16
Accepted
time: 0ms
memory: 3800kb
input:
3 2 0 0 0 1 0 2 100 0 1 2 2 2 1 1 1 0 0 2 2 1 2 0 2 0 1 0 0 0 1 0 2 2 1 1 0 2 2 2 0 0 0 0 2 1 1 1 2 2 2 2 1 0 0 2 2 0 1 1 0 0 0 2 0 1 1 1 0 2 1 2 0 0 2 0 1 2 2 1 1 0 0 0 1 2 1 0 0 2 0 0 1 2 1 2 0 0 2 2 2 0 1 2 0 0 0 0 1 2 1 0 2 0 1 0 2 2 2 1 0 1 1 1 2 1 0 1 2 1 0 0 0 1 1 0 1 1 0 2 0 1 2 1 0 0 2 0 0 ...
output:
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
result:
ok
Test #61:
score: -16
Wrong Answer
time: 1ms
memory: 4084kb
input:
4 1 0 1 0 0 1 0 2 1 3 100 0 2 3 2 1 1 0 1 3 1 3 2 3 1 2 2 1 2 2 1 1 0 2 2 3 2 3 1 1 1 3 2 2 0 3 1 0 2 1 2 2 1 2 2 0 1 1 0 3 0 3 2 3 1 3 0 0 0 2 0 1 1 1 2 0 1 1 0 2 2 2 1 1 1 3 2 0 0 2 2 0 1 3 1 1 0 2 1 2 0 1 2 0 2 3 0 3 1 0 1 0 2 3 2 3 1 1 1 1 0 2 2 0 0 0 1 0 0 0 1 0 0 2 0 0 1 3 2 0 2 3 0 2 2 2 1 3 ...
output:
0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 2 0 0 0 0 0 0 1 2 1 1 2 0 0 0 0 1 0 2 0 0 0 1 1 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
result:
wrong answer
Subtask #6:
score: 0
Skipped
Dependency #2:
0%
Subtask #7:
score: 0
Skipped
Dependency #1:
0%