#include <bits/stdc++.h>
struct Seg {
std::vector <long long> m, v, w;
int size;
Seg(int s) {
size = 1;
while (size < s) {
size <<= 1;
}
m.resize(size << 1, 0);
v.resize(size << 1, 0);
w.resize(size << 1, 0);
}
void reset(int s) {
//bool rez = size < s;
//while (size < s) {
//size <<= 1;
//}
//if (rez) {
//m.resize(size << 1);
//v.resize(size << 1);
//w.resize(size << 1);
//}
m.assign(size << 1, 0);
v.assign(size << 1, 0);
w.assign(size << 1, 0);
}
void update(int l, int r, long long delta) {
update(l, r, delta, 0, 0, size);
}
void update(int tl, int tr, long long delta, int now, int l, int r) {
push(now, l, r);
if (l >= tr || r <= tl) {
return;
}
if (l >= tl && r <= tr) {
w[now] += delta;
push(now, l, r);
return;
}
int mid = (l + r) >> 1;
update(tl, tr, delta, now * 2 + 1, l, mid);
update(tl, tr, delta, now * 2 + 2, mid, r);
v[now] = v[now * 2 + 1] + v[now * 2 + 2];
m[now] = std::max(m[now * 2 + 1], m[now * 2 + 2]);
}
long long query(int l, int r) {
return query(l, r, 0, 0, size);
}
bool outside(int l, int r, int tl, int tr) {
return l >= tr || r <= tl;
}
long long query(int tl, int tr, int now, int l, int r) {
push(now, l, r);
if (l >= tl && r <= tr) {
return m[now];
}
int mid = (l + r) >> 1;
long long ret = 0;
if (outside(l, mid, tl, tr)) {
ret = query(tl, tr, (now << 1) + 2, mid, r);
} else {
if (outside(mid, r, tl, tr)) {
ret = query(tl, tr, (now << 1) + 1, l, mid);
} else {
ret = std::max(
query(tl, tr, (now << 1) + 1, l, mid),
query(tl, tr, (now << 1) + 2, mid, r));
}
}
return ret;
}
void push(int node, int l, int r) {
v[node] += w[node] * (r - l);
m[node] += w[node];
if (r - l - 1) {
w[node * 2 + 1] += w[node];
w[node * 2 + 2] += w[node];
}
w[node] = 0;
}
};
int n;
std::vector <std::vector <std::pair <int, std::pair <int, int>>>> g;
std::vector <std::vector <int>> c;
std::vector <int> cc;
std::vector <long long> cans;
void fc(int node, std::vector <bool>& vis) {
if (vis[node]) {
return;
}
vis[node] = true;
c.back().push_back(node);
for (auto p : g[node]) {
fc(p.second.first, vis);
}
}
std::vector <bool> cyc;
bool cy(int node, int par, std::vector <bool>& vis) {
if (vis[node]) {
return cyc[node] = true;
}
vis[node] = true;
for (auto p : g[node]) {
if (p.first != par && cy(p.second.first, p.first, vis)) {
return cyc[node] ? false : (cyc[node] = true);
}
}
return false;
}
long long td(int node, int par = -1) {
std::vector <long long> ch;
for (auto p : g[node]) {
if (p.second.first == par || cyc[p.second.first]) {
continue;
}
ch.push_back(td(p.second.first, node) + p.second.second);
}
std::sort(ch.rbegin(), ch.rend());
if (ch.size()) {
cans[cc[node]] =
std::max(cans[cc[node]], (int) ch.size() > 1 ? ch[0] + ch[1] : ch.empty() ? 0LL : ch[0]);
}
return ch.size() ? ch[0] : 0LL;
}
std::vector <long long> sus;
void gse(int node, int par, std::vector <bool>& vis, std::vector <std::pair <long long, int>>& seq) {
for (auto p : g[node]) {
if (p.second.first != par && cyc[p.second.first] && !vis[p.second.first]) {
vis[p.second.first] = true;
seq.emplace_back(sus[p.second.first], p.second.second);
gse(p.second.first, node, vis, seq);
}
}
}
int main() {
std::ios::sync_with_stdio(0); std::cin.tie(0);
std::cin >> n;
g.resize(n);
for (int i = 0; i < n; i++) {
int u, w; std::cin >> u >> w; u--;
g[u].push_back({ i, { i, w } });
g[i].push_back({ i, { u, w } });
}
std::vector <bool> vis(n, false);
cc.resize(n, -1);
for (int i = 0; i < n; i++) {
if (vis[i]) {
continue;
}
c.resize(c.size() + 1);
cans.resize(cans.size() + 1, 0);
fc(i, vis);
for (int x : c.back()) {
cc[x] = (int) c.size() - 1;
}
}
cyc.resize(n, false);
vis.assign(n, false);
for (auto& v : c) {
cy(v[0], -1, vis);
}
sus.resize(n, 0);
for (int i = 0; i < n; i++) {
if (cyc[i]) {
sus[i] = td(i);
}
}
vis.assign(n, false);
Seg seg(n);
for (int i = 0; i < n; i++) {
if (!vis[i] && cyc[i]) {
std::vector <std::pair <long long, int>> seq;
gse(i, -1, vis, seq);
if ((int) seq.size() < 2) {
seq.clear();
for (int x : c[cc[i]]) {
if (cyc[x]) {
for (auto p : g[x]) {
if (cyc[p.second.first]) {
seq.emplace_back(sus[p.second.first], p.second.second);
}
}
}
}
std::sort(seq.begin(), seq.end(), [] (
std::pair <long long, int> u, std::pair <long long, int> v) {
return u.second < v.second;
});
seq = { seq.front(), seq.back() };
}
int m = seq.size();
seg.reset(m);
long long sum = 0;
for (int j = 0; j < m; j++) {
seg.update(j, j + 1, seq[j].first + (sum += seq[j].second));
}
for (int j = 0; j < m; j++) {
seg.update(0, m, -seq[j].second);
seg.update(j, j + 1, -seg.query(j, j + 1));
if (j) {
seg.update(j - 1, j, -seg.query(j - 1, j));
seg.update(j - 1, j, sum + seq[j - 1].first - seq[j].second);
}
cans[cc[i]] = std::max(cans[cc[i]], seq[j].first + seg.query(0, m));
}
}
}
long long ans = 0;
for (long long x : cans) {
ans += x;
}
std::cout << ans << "\n";
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
212 KB |
Output is correct |
2 |
Correct |
1 ms |
340 KB |
Output is correct |
3 |
Correct |
1 ms |
340 KB |
Output is correct |
4 |
Correct |
0 ms |
212 KB |
Output is correct |
5 |
Correct |
0 ms |
212 KB |
Output is correct |
6 |
Correct |
1 ms |
212 KB |
Output is correct |
7 |
Correct |
0 ms |
212 KB |
Output is correct |
8 |
Correct |
1 ms |
340 KB |
Output is correct |
9 |
Correct |
0 ms |
212 KB |
Output is correct |
10 |
Correct |
1 ms |
340 KB |
Output is correct |
11 |
Correct |
1 ms |
340 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2 ms |
468 KB |
Output is correct |
2 |
Correct |
7 ms |
468 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
5 ms |
596 KB |
Output is correct |
2 |
Correct |
6 ms |
980 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
21 ms |
2652 KB |
Output is correct |
2 |
Correct |
56 ms |
8136 KB |
Output is correct |
3 |
Correct |
13 ms |
3708 KB |
Output is correct |
4 |
Correct |
6 ms |
2004 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
70 ms |
10020 KB |
Output is correct |
2 |
Correct |
201 ms |
16824 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
147 ms |
31500 KB |
Output is correct |
2 |
Correct |
468 ms |
39544 KB |
Output is correct |
3 |
Correct |
494 ms |
50108 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
764 ms |
58756 KB |
Output is correct |
2 |
Correct |
702 ms |
88764 KB |
Output is correct |
3 |
Correct |
1761 ms |
124916 KB |
Output is correct |
4 |
Runtime error |
262 ms |
131072 KB |
Execution killed with signal 9 |
5 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Runtime error |
390 ms |
131072 KB |
Execution killed with signal 9 |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Runtime error |
354 ms |
131072 KB |
Execution killed with signal 9 |
2 |
Halted |
0 ms |
0 KB |
- |