This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#pragma GCC optimize("O3")
#include <algorithm>
#include <iostream>
#include <vector>
using i64 = int64_t;
using i32 = int32_t;
struct Operation {
i32 l1, r1;
};
constexpr i64 root(i64 n) {
i64 i = 0;
for (; i * i <= n; i++)
;
return i - 1;
}
class UnionFind {
std::vector<i32> parent;
std::vector<i32> sizes;
std::vector<bool> edge_parity;
std::vector<Operation> operations;
public:
UnionFind(size_t sz)
: parent(sz, -1), sizes(sz, 1), edge_parity(sz, false), operations() {}
template <bool PATH_COMPRESSION>
i32 find(i32 idx) {
if (parent[idx] < 0)
return idx;
else if constexpr (PATH_COMPRESSION) {
i64 root = find<PATH_COMPRESSION>(parent[idx]);
edge_parity[idx] = edge_parity[idx] ^ edge_parity[parent[idx]];
return parent[idx] = root;
} else
return find<PATH_COMPRESSION>(parent[idx]);
}
bool parity(i32 idx) {
if (parent[idx] < 0)
return false;
else
return parity(parent[idx]) ^ edge_parity[idx];
}
template <bool PATH_COMPRESSION>
std::pair<i32, bool> both(i32 idx) {
if constexpr (PATH_COMPRESSION) {
return {find<true>(idx), parity(idx)};
} else {
// in this case there's an easy iterative version
bool parity = false;
while (parent[idx] >= 0) {
parity = parity ^ edge_parity[idx];
idx = parent[idx];
}
return {idx, parity};
}
}
template <bool PATH_COMPRESSION>
bool lag_fagforening(i32 l, i32 r) {
auto [l1, lp] = both<PATH_COMPRESSION>(l);
auto [r1, rp] = both<PATH_COMPRESSION>(r);
operations.push_back({
.l1 = l1,
.r1 = r1,
});
if (l1 == r1) {
return lp != rp;
} else {
if (sizes[l1] < sizes[r1]) {
std::swap(l1, r1);
std::swap(lp, rp);
}
sizes[l1] += sizes[r1];
parent[r1] = l1;
edge_parity[r1] = 1 ^ lp ^ rp;
return true;
}
}
void tvungen_lønnsnemnd() {
auto [l1, r1] = operations.back();
operations.pop_back();
if (parent[r1] == l1) {
parent[r1] = -1;
sizes[l1] -= sizes[r1];
} else if (parent[l1] == r1) {
parent[l1] = -1;
sizes[r1] -= sizes[l1];
}
edge_parity[l1] = edge_parity[r1] = false;
}
};
struct {
template <typename T>
operator T() const {
T x;
std::cin >> x;
return x;
}
} in;
#define entire(v) std::begin(v), std::end(v)
#pragma GCC diagnostic ignored "-Wreturn-type"
main() {
std::cin.tie(nullptr)->sync_with_stdio(false);
i32 n, m, q;
std::cin >> n >> m >> q;
std::vector<std::pair<i32, i32>> edges(m);
for (i32 i = 0; i < m; i++) {
edges[i] = {(i32)in - 1, (i32)in - 1};
}
UnionFind dsu(n);
static constexpr i32 root_m = 1024;
struct Query {
i32 l, r, i;
};
std::vector<Query> queries(q);
for (i32 i = 0; i < q; i++) queries[i] = {(i32)in - 1, (i32)in, i};
std::sort(entire(queries), [](auto &&lhs, auto &&rhs) {
return std::pair<i32, i32>{lhs.l / root_m, -lhs.r} <
std::pair<i32, i32>{rhs.l / root_m, -rhs.r};
});
std::vector<bool> answers(q);
i32 l = 0;
i32 r = 0;
bool is_bipartite_left = true;
for (i32 start = 0; start < m && is_bipartite_left; start += root_m) {
while (r < q && queries[r].l < start + root_m) r++;
bool is_bipartite_right = true;
i32 w = m;
for (; l < r && is_bipartite_right; l++) {
for (; w > queries[l].r && is_bipartite_right; w--)
is_bipartite_right &= dsu.lag_fagforening<false>(edges[w - 1].first, edges[w - 1].second);
if (!is_bipartite_right) break;
bool is_bipartite = true;
i32 g = start;
for (; g < queries[l].l && is_bipartite; g++)
is_bipartite &= dsu.lag_fagforening<false>(edges[g].first, edges[g].second);
answers[queries[l].i] = is_bipartite;
for (i32 u = start; u < g; u++) dsu.tvungen_lønnsnemnd();
}
for (; l < r; l++)
answers[queries[l].i] = false;
for (i32 x = w; x < m; x++) dsu.tvungen_lønnsnemnd();
for (i32 y = start; y < start + root_m && y < m; y++)
is_bipartite_left &= dsu.lag_fagforening<true>(edges[y].first, edges[y].second);
}
for (; l < q; l++)
answers[queries[l].i] = false;
for (auto x : answers) {
std::cout << (x ? "NO\n" : "YES\n");
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |