#include <bits/stdc++.h>
#include "collapse.h"
using i32 = std::int32_t;
using u32 = std::uint32_t;
using i64 = std::int64_t;
using u64 = std::uint64_t;
using i128 = __int128_t;
using u128 = __uint128_t;
using isize = std::ptrdiff_t;
using usize = std::size_t;
class rep {
struct Iter {
usize itr;
constexpr Iter(const usize pos) noexcept : itr(pos) {}
constexpr void operator++() noexcept { ++itr; }
constexpr bool operator!=(const Iter& other) const noexcept { return itr != other.itr; }
constexpr usize operator*() const noexcept { return itr; }
};
const Iter first, last;
public:
explicit constexpr rep(const usize first, const usize last) noexcept : first(first), last(std::max(first, last)) {}
constexpr Iter begin() const noexcept { return first; }
constexpr Iter end() const noexcept { return last; }
};
class RollbackUnionFind {
std::vector<usize> data;
std::stack<std::pair<usize, usize>> history;
public:
explicit RollbackUnionFind(const usize size = 0) : data(size, -1), history() {}
usize size() const { return data.size(); }
usize leader(usize u) const {
assert(u < size());
while (data[u] < size()) u = data[u];
return u;
}
usize size(const usize u) const {
assert(u < size());
return -data[leader(u)];
}
std::pair<usize, bool> merge(usize u, usize v) {
assert(u < size());
assert(v < size());
u = leader(u);
v = leader(v);
if (u == v) return std::make_pair(u, false);
if (data[u] > data[v]) std::swap(u, v);
history.emplace(u, data[u]);
history.emplace(v, data[v]);
data[u] += data[v];
data[v] = u;
return std::make_pair(u, true);
}
bool same(const usize u, const usize v) const {
assert(u < size());
assert(v < size());
return leader(u) == leader(v);
}
void rollback(const usize steps) {
assert(2 * steps <= history.size());
for (usize i = 2 * steps; i > 0; --i) {
const auto [k, x] = history.top();
history.pop();
data[k] = x;
}
}
};
template <class T> using Vec = std::vector<T>;
constexpr usize BSIZE = 400;
Vec<int> calc(const usize N, Vec<int> T, Vec<int> X, Vec<int> Y, Vec<int> W, Vec<int> P) {
const auto C = T.size();
const auto Q = W.size();
Vec<std::pair<int, int>> edge;
edge.reserve(C);
for (const auto i : rep(0, C)) {
if (X[i] > Y[i]) {
std::swap(X[i], Y[i]);
}
edge.emplace_back(Y[i], X[i]);
}
std::sort(edge.begin(), edge.end());
edge.erase(std::unique(edge.begin(), edge.end()), edge.end());
Vec<usize> eid(C);
for (const auto i : rep(0, C)) {
eid[i] = std::lower_bound(edge.begin(), edge.end(), std::make_pair(Y[i], X[i])) - edge.begin();
}
const auto Blocks = (C + BSIZE - 1) / BSIZE;
Vec<Vec<usize>> qid(Blocks);
for (const auto i : rep(0, Q)) {
qid[W[i] / BSIZE].push_back(i);
}
Vec<int> ret(Q);
for (const auto block : rep(0, Blocks)) {
const auto low = BSIZE * block;
const auto high = std::min(C, low + BSIZE);
auto& qs = qid[block];
std::sort(qs.begin(), qs.end(), [&](const usize i, const usize j) { return P[i] < P[j]; });
Vec<char> usage(edge.size()), changes(edge.size());
for (const auto i : rep(0, low)) {
usage[eid[i]] ^= 1;
}
for (const auto i : rep(low, high)) {
changes[eid[i]] = true;
}
Vec<usize> naive;
for (const auto i : rep(0, edge.size())) {
if (changes[i]) {
naive.push_back(i);
}
}
RollbackUnionFind dsu(N);
usize comps = N, seen = 0;
for (const auto i : qs) {
while (seen < edge.size() and edge[seen].first <= P[i]) {
if (!changes[seen] and usage[seen]) {
comps -= dsu.merge(edge[seen].first, edge[seen].second).second;
}
seen += 1;
}
const auto memo = comps;
for (const auto j : rep(low, W[i] + 1)) {
usage[eid[j]] ^= 1;
}
for (const auto e : naive) {
if (usage[e] and edge[e].first <= P[i]) {
comps -= dsu.merge(edge[e].first, edge[e].second).second;
}
}
for (const auto j : rep(low, W[i] + 1)) {
usage[eid[j]] ^= 1;
}
ret[i] = comps;
dsu.rollback(memo - comps);
comps = memo;
}
}
return ret;
}
Vec<int> simulateCollapse(int N, Vec<int> T, Vec<int> X, Vec<int> Y, Vec<int> W, Vec<int> P) {
const auto C = T.size();
const auto Q = W.size();
auto ret = calc(N, T, X, Y, W, P);
for (const auto i : rep(0, C)) {
X[i] = N - X[i] - 1;
Y[i] = N - Y[i] - 1;
}
for (const auto i : rep(0, Q)) {
P[i] = N - P[i] - 2;
}
const auto tmp = calc(N, T, X, Y, W, P);
for (const auto i : rep(0, Q)) {
ret[i] += tmp[i];
ret[i] -= N;
}
return ret;
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
25 ms |
716 KB |
Output is correct |
2 |
Correct |
4 ms |
460 KB |
Output is correct |
3 |
Correct |
7 ms |
584 KB |
Output is correct |
4 |
Correct |
8 ms |
460 KB |
Output is correct |
5 |
Correct |
28 ms |
816 KB |
Output is correct |
6 |
Correct |
47 ms |
832 KB |
Output is correct |
7 |
Correct |
4 ms |
588 KB |
Output is correct |
8 |
Correct |
5 ms |
588 KB |
Output is correct |
9 |
Correct |
33 ms |
920 KB |
Output is correct |
10 |
Correct |
63 ms |
944 KB |
Output is correct |
11 |
Correct |
77 ms |
1020 KB |
Output is correct |
12 |
Correct |
72 ms |
956 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
40 ms |
5116 KB |
Output is correct |
2 |
Correct |
54 ms |
5136 KB |
Output is correct |
3 |
Correct |
673 ms |
11076 KB |
Output is correct |
4 |
Correct |
128 ms |
5272 KB |
Output is correct |
5 |
Correct |
1016 ms |
11428 KB |
Output is correct |
6 |
Correct |
735 ms |
5332 KB |
Output is correct |
7 |
Correct |
1247 ms |
11768 KB |
Output is correct |
8 |
Correct |
1185 ms |
12292 KB |
Output is correct |
9 |
Correct |
44 ms |
6416 KB |
Output is correct |
10 |
Correct |
71 ms |
6380 KB |
Output is correct |
11 |
Correct |
875 ms |
6424 KB |
Output is correct |
12 |
Correct |
1230 ms |
13108 KB |
Output is correct |
13 |
Correct |
1731 ms |
13264 KB |
Output is correct |
14 |
Correct |
1946 ms |
14020 KB |
Output is correct |
15 |
Correct |
1798 ms |
14272 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
40 ms |
5144 KB |
Output is correct |
2 |
Correct |
57 ms |
5140 KB |
Output is correct |
3 |
Correct |
89 ms |
5256 KB |
Output is correct |
4 |
Correct |
135 ms |
5212 KB |
Output is correct |
5 |
Correct |
877 ms |
5276 KB |
Output is correct |
6 |
Correct |
769 ms |
5612 KB |
Output is correct |
7 |
Correct |
1311 ms |
10676 KB |
Output is correct |
8 |
Correct |
2009 ms |
12400 KB |
Output is correct |
9 |
Correct |
63 ms |
6344 KB |
Output is correct |
10 |
Correct |
1117 ms |
6648 KB |
Output is correct |
11 |
Correct |
2865 ms |
15660 KB |
Output is correct |
12 |
Correct |
3402 ms |
15816 KB |
Output is correct |
13 |
Correct |
2861 ms |
15432 KB |
Output is correct |
14 |
Correct |
3429 ms |
15836 KB |
Output is correct |
15 |
Correct |
2810 ms |
15356 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
25 ms |
716 KB |
Output is correct |
2 |
Correct |
4 ms |
460 KB |
Output is correct |
3 |
Correct |
7 ms |
584 KB |
Output is correct |
4 |
Correct |
8 ms |
460 KB |
Output is correct |
5 |
Correct |
28 ms |
816 KB |
Output is correct |
6 |
Correct |
47 ms |
832 KB |
Output is correct |
7 |
Correct |
4 ms |
588 KB |
Output is correct |
8 |
Correct |
5 ms |
588 KB |
Output is correct |
9 |
Correct |
33 ms |
920 KB |
Output is correct |
10 |
Correct |
63 ms |
944 KB |
Output is correct |
11 |
Correct |
77 ms |
1020 KB |
Output is correct |
12 |
Correct |
72 ms |
956 KB |
Output is correct |
13 |
Correct |
40 ms |
5116 KB |
Output is correct |
14 |
Correct |
54 ms |
5136 KB |
Output is correct |
15 |
Correct |
673 ms |
11076 KB |
Output is correct |
16 |
Correct |
128 ms |
5272 KB |
Output is correct |
17 |
Correct |
1016 ms |
11428 KB |
Output is correct |
18 |
Correct |
735 ms |
5332 KB |
Output is correct |
19 |
Correct |
1247 ms |
11768 KB |
Output is correct |
20 |
Correct |
1185 ms |
12292 KB |
Output is correct |
21 |
Correct |
44 ms |
6416 KB |
Output is correct |
22 |
Correct |
71 ms |
6380 KB |
Output is correct |
23 |
Correct |
875 ms |
6424 KB |
Output is correct |
24 |
Correct |
1230 ms |
13108 KB |
Output is correct |
25 |
Correct |
1731 ms |
13264 KB |
Output is correct |
26 |
Correct |
1946 ms |
14020 KB |
Output is correct |
27 |
Correct |
1798 ms |
14272 KB |
Output is correct |
28 |
Correct |
40 ms |
5144 KB |
Output is correct |
29 |
Correct |
57 ms |
5140 KB |
Output is correct |
30 |
Correct |
89 ms |
5256 KB |
Output is correct |
31 |
Correct |
135 ms |
5212 KB |
Output is correct |
32 |
Correct |
877 ms |
5276 KB |
Output is correct |
33 |
Correct |
769 ms |
5612 KB |
Output is correct |
34 |
Correct |
1311 ms |
10676 KB |
Output is correct |
35 |
Correct |
2009 ms |
12400 KB |
Output is correct |
36 |
Correct |
63 ms |
6344 KB |
Output is correct |
37 |
Correct |
1117 ms |
6648 KB |
Output is correct |
38 |
Correct |
2865 ms |
15660 KB |
Output is correct |
39 |
Correct |
3402 ms |
15816 KB |
Output is correct |
40 |
Correct |
2861 ms |
15432 KB |
Output is correct |
41 |
Correct |
3429 ms |
15836 KB |
Output is correct |
42 |
Correct |
2810 ms |
15356 KB |
Output is correct |
43 |
Correct |
1099 ms |
11716 KB |
Output is correct |
44 |
Correct |
1613 ms |
11864 KB |
Output is correct |
45 |
Correct |
1367 ms |
12200 KB |
Output is correct |
46 |
Correct |
2024 ms |
12492 KB |
Output is correct |
47 |
Correct |
65 ms |
6388 KB |
Output is correct |
48 |
Correct |
86 ms |
6348 KB |
Output is correct |
49 |
Correct |
1020 ms |
6268 KB |
Output is correct |
50 |
Correct |
1361 ms |
7420 KB |
Output is correct |
51 |
Correct |
1399 ms |
13108 KB |
Output is correct |
52 |
Correct |
2139 ms |
13776 KB |
Output is correct |
53 |
Correct |
2079 ms |
13836 KB |
Output is correct |
54 |
Correct |
2507 ms |
14440 KB |
Output is correct |
55 |
Correct |
2347 ms |
14180 KB |
Output is correct |
56 |
Correct |
2557 ms |
14840 KB |
Output is correct |
57 |
Correct |
2669 ms |
15036 KB |
Output is correct |
58 |
Correct |
3302 ms |
15488 KB |
Output is correct |
59 |
Correct |
2814 ms |
15404 KB |
Output is correct |
60 |
Correct |
3572 ms |
15836 KB |
Output is correct |