This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200005;
int N, M, Q;
pair<int, int> edges[MAXN];
// Disjoint Set with rollbacks
int par[MAXN * 2];
int sz[MAXN * 2];
vector<pair<int, int>> hist;
int Find(int x) {
return par[x] == x ? x : Find(par[x]);
}
int Unite(int x, int y) {
x = Find(x), y = Find(y);
if (x == y) return 0;
if (sz[x] > sz[y]) swap(x, y);
hist.emplace_back(x, par[x]);
hist.emplace_back(y, sz[y]);
par[x] = y;
sz[y] += sz[x];
return 1;
}
void Rollback(int x) {
while (x--) {
sz[hist.back().first] = hist.back().second;
hist.pop_back();
par[hist.back().first] = hist.back().second;
hist.pop_back();
}
}
int last[MAXN]; // last[L] = highest R, such that erasing edges = [L...R), odd cycle still exist
void FindOpt(int ll, int lr, int rl, int rr) {
if (ll > lr) return;
int l = (ll + lr) / 2;
int r = rr;
int ops = 0;
int odd_cycle = 0;
for (int i = ll; i < l; i++) {
ops += Unite(edges[i].first + MAXN, edges[i].second);
ops += Unite(edges[i].first, edges[i].second + MAXN);
if (Find(edges[i].first) == Find(edges[i].first + MAXN)) {
odd_cycle = 1;
Rollback(ops); ops = 0;
last[l] = r = M + 1;
break;
}
}
for (int i = rr; odd_cycle == 0 && i >= max(l, rl); i--) {
ops += Unite(edges[i].first + MAXN, edges[i].second);
ops += Unite(edges[i].first, edges[i].second + MAXN);
if (Find(edges[i].first) == Find(edges[i].first + MAXN)) {
last[l] = r = i;
Rollback(ops); ops = 0;
break;
}
}
odd_cycle = 0;
for (int i = r + 1; i <= rr; i++) {
ops += Unite(edges[i].first + MAXN, edges[i].second);
ops += Unite(edges[i].first, edges[i].second + MAXN);
if (Find(edges[i].first) == Find(edges[i].first + MAXN)) {
odd_cycle = 1;
Rollback(ops); ops = 0;
for (int j = ll; j < l; j++) {
last[j] = M + 1;
}
break;
}
}
if (odd_cycle == 0) {
FindOpt(ll, l - 1, rl, r);
Rollback(ops); ops = 0;
}
odd_cycle = 0;
for (int i = ll; i <= l; i++) {
ops += Unite(edges[i].first + MAXN, edges[i].second);
ops += Unite(edges[i].first, edges[i].second + MAXN);
if (Find(edges[i].first) == Find(edges[i].first + MAXN)) {
odd_cycle = 1;
Rollback(ops); ops = 0;
for (int j = l + 1; j <= lr; j++) {
last[j] = M + 1;
}
break;
}
}
if (odd_cycle == 0) {
FindOpt(l + 1, lr, r, rr);
Rollback(ops); ops = 0;
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
iota(par, par + MAXN * 2, 0);
fill(sz, sz + MAXN * 2, 1);
cin >> N >> M >> Q;
for (int i = 1; i <= M; i++) {
cin >> edges[i].first >> edges[i].second;
}
edges[M + 1].first = N + 1, edges[M + 1].second = N + 2;
FindOpt(1, M, 1, M + 1);
for (int i = 1; i <= Q; i++) {
int l, r;
cin >> l >> r;
if (r < last[l]) {
cout << "YES\n";
} else {
cout << "NO\n";
}
}
return 0;
}
# | 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... |