QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#370539 | #6350. MIT | alpha1022 | WA | 1ms | 4144kb | C++14 | 5.6kb | 2024-03-29 10:33:41 | 2024-03-29 10:33:46 |
Judging History
answer
#include <bits/stdc++.h>
#define lg __lg
using namespace std;
const int BUFF_SIZE = 1 << 20;
char BUFF[BUFF_SIZE], *BB, *BE;
char gc() { return BB == BE ? (BE = (BB = BUFF) + fread(BUFF, 1, BUFF_SIZE, stdin), BB == BE ? EOF : *BB++) : *BB++; }
void read() {}
template<class T, class ...Ts>
void read(T &x, Ts &...args) {
x = 0; char ch = 0, w = 0;
while (ch < '0' || ch > '9') w |= ch == '-', ch = gc();
while (ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = gc();
if (w) x = -x;
read(args...);
}
using ll = long long;
const int N = 1e6;
const int LG = 20;
int n;
tuple<int, int, int> edge[N + 5];
pair<int, int> e[N * 2 + 5];
int deg[N + 5], fir[N + 5];
int fa[N + 5], faw[N + 5];
ll dis[N + 5];
int id[N + 5], rk[N + 5], alca[N + 5], siz[N + 5], son[N + 5], top[N + 5];
void dfs1(int u) {
siz[u] = 1;
for (int i = 1; i <= deg[u]; ++i) {
auto [v, w] = e[fir[u] + i];
if (v != fa[u]) {
fa[v] = u, faw[v] = w, dis[v] = dis[u] + w, dfs1(v), siz[u] += siz[v];
if (!son[u] || siz[v] > siz[son[u]]) son[u] = v;
}
}
}
int stk[N + 5], stkTop;
void dfs2(int u) {
static int tot = 0;
rk[id[u] = ++tot] = u;
if (tot > 1) alca[tot] = id[stk[stkTop]];
stk[++stkTop] = u;
if (son[u]) top[son[u]] = top[u], dfs2(son[u]);
for (int i = 1; i <= deg[u]; ++i) {
auto [v, _] = e[fir[u] + i];
if (v != fa[u] && v != son[u])
top[v] = v, dfs2(v);
}
--stkTop;
}
struct SparseTable {
int st[LG][N + 5];
void build() {
for (int i = 2; i <= n; ++i) st[0][i] = alca[i];
for (int k = 0; 2 << k < n; ++k)
for (int i = (2 << k) + 1; i <= n; ++i)
st[k + 1][i] = min(st[k][i], st[k][i - (1 << k)]);
}
int lca(int u, int v) {
if (u == v) return u;
int l = id[u], r = id[v];
if (l > r) swap(l, r);
int k = lg(r - l);
return rk[min(st[k][r], st[k][l + (1 << k)])];
}
} st;
struct SegmentTree {
#define ls (u << 1)
#define rs (ls | 1)
struct node {
ll sum, wsum;
int max, add;
} seg[N * 4 + 5];
void pushUp(int u) {
seg[u].sum = seg[ls].sum + seg[rs].sum + seg[u].add * seg[u].wsum,
seg[u].max = max(seg[ls].max, seg[rs].max) + seg[u].add;
}
void build(int u, int tl, int tr) {
if (tl == tr) { seg[u].wsum = faw[rk[tl]]; return ; }
int mid = (tl + tr) >> 1;
build(ls, tl, mid), build(rs, mid + 1, tr);
seg[u].wsum = seg[ls].wsum + seg[rs].wsum;
}
void apply(int k, int u) { seg[u].sum += k * seg[u].wsum, seg[u].max += k, seg[u].add += k; }
void update(int l, int r, int k, int u, int tl, int tr) {
if (l <= tl && tr <= r) return apply(k, u);
int mid = (tl + tr) >> 1;
if (l <= mid) update(l, r, k, ls, tl, mid);
if (r > mid) update(l, r, k, rs, mid + 1, tr);
pushUp(u);
}
int query(int k, int u, int tl, int tr) {
if (tl == tr) return rk[tl];
int mid = (tl + tr) >> 1;
k -= seg[u].add;
return seg[rs].max >= k ? query(k, rs, mid + 1, tr) : query(k, ls, tl, mid);
}
ll querySum(int l, int r, int k, int u, int tl, int tr) {
if (l <= tl && tr <= r) return seg[u].sum + k * seg[u].wsum;
int mid = (tl + tr) >> 1;
ll ret = 0; k += seg[u].add;
if (l <= mid) ret += querySum(l, r, k, ls, tl, mid);
if (r > mid) ret += querySum(l, r, k, rs, mid + 1, tr);
return ret;
}
} seg;
ll dist(int u, int v) { return dis[u] + dis[v] - dis[st.lca(u, v)] * 2; }
tuple<ll, int, int> path(int u, int v) { if (!u || !v) return {-1, 0, 0}; return {dist(u, v), u, v}; }
struct SegmentTree1 {
#define ls (u << 1)
#define rs (ls | 1)
tuple<ll, int, int> seg[N * 4 + 5];
void pushUp(int u) {
seg[u] = max({
seg[ls], seg[rs],
path(get<1>(seg[ls]), get<1>(seg[rs])),
path(get<1>(seg[ls]), get<2>(seg[rs])),
path(get<2>(seg[ls]), get<1>(seg[rs])),
path(get<2>(seg[ls]), get<2>(seg[rs]))
});
}
void build(int u, int tl, int tr) {
if (tl == tr) { seg[u] = {0, tl, tl}; return ; }
int mid = (tl + tr) >> 1;
build(ls, tl, mid), build(rs, mid + 1, tr);
pushUp(u);
}
void erase(int x, int u, int tl, int tr) {
if (tl == tr) { seg[u] = {-1, 0, 0}; return ; }
int mid = (tl + tr) >> 1;
if (x <= mid) erase(x, ls, tl, mid);
else erase(x, rs, mid + 1, tr);
pushUp(u);
}
} seg1;
void update(int u) {
seg1.erase(u, 1, 1, n);
for (; u; u = fa[top[u]])
seg.update(id[top[u]], id[u], 1, 1, 1, n);
}
int centroid;
int queryCentroid(int sum) { return rk[seg.query((sum + 1) >> 1, 1, 1, n)]; }
pair<ll, int> query(int u) {
auto [_, v, w] = seg1.seg[1];
return max(make_pair(dist(u, v), v), make_pair(dist(u, w), w));
}
ll querySum(int u) {
ll ret = 0;
for (; u; u = fa[top[u]])
ret += seg.querySum(id[top[u]], id[u], 0, 1, 1, n);
return ret;
}
ll ans;
int main() {
read(n);
for (int i = 1; i < n; ++i) {
auto &[u, v, w] = edge[i];
read(u, v, w), ++deg[u], ++deg[v];
}
if (n == 1) return 0;
for (int i = 1; i <= n; ++i) fir[i] = fir[i - 1] + deg[i];
for (int i = 1; i < n; ++i) {
auto [u, v, w] = edge[i];
e[fir[u]--] = {v, w}, e[fir[v]--] = {u, w};
}
dfs1(1), top[1] = 1, dfs2(1), st.build(), seg.build(1, 1, n), seg1.build(1, 1, n);
auto [_, u, v] = seg1.seg[1]; ans = dis[u] + dis[v];
update(u), update(v), centroid = queryCentroid(2);
printf("%lld%c", _, " \n"[1 == n / 2]);
for (int k = 3; k <= n; ++k) {
auto [_, u] = query(centroid);
ans += dis[u], update(u);
if (k & 1) centroid = queryCentroid(k);
else printf("%lld%c", ans + dis[centroid] * k - querySum(centroid) * 2, " \n"[k / 2 == n / 2]);
}
}
详细
Test #1:
score: 100
Accepted
time: 1ms
memory: 3924kb
input:
7 1 3 99 2 3 82 3 4 4 4 5 43 5 6 5 4 7 3
output:
181 280 287
result:
ok 3 number(s): "181 280 287"
Test #2:
score: -100
Wrong Answer
time: 1ms
memory: 4144kb
input:
1000 328 12 58771429 881 504 17030494 847 622 20805817 12 922 58532669 879 929 52585738 495 726 27873950 855 17 37971674 797 941 76999719 702 610 719916 479 127 97829887 731 557 55300256 282 615 88802280 651 318 64099880 540 51 6547869 896 54 87823596 674 879 80674008 77 691 54802376 193 851 7869172...
output:
48829042195 102543662811 130652734539 194713456438 280455873830 321598213726 353589035922 571256926507 253006216129 442226468411 460746590458 538104633569 626793764008 685007308839 738198028334 832759765856 889843038672 723518449686 798274972434 893332419608 974198034878 1050093110804 1096582356539 ...
result:
wrong answer 2nd numbers differ - expected: '97562386542', found: '102543662811'