题解:P7843 「C.E.L.U-03」布尔
SleepinGod · · 题解
考虑限制
考虑设
在这之前我们先考虑新加入一个限制的时候如何判断此时是否合法。设
考虑如何求解
总的可以做到
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
int mx[N], n, m, q, h, t, siz[N], fa[N], c[N][2], tot, f[N][22];
struct A {
int x, y;
} st[N * 2];
struct S {
int u, x, v, y;
} a[N];
int find(int x) {
return (x == fa[x] ? x : find(fa[x]));
}
void merge(int x, int y) {
x = find(x), y = find(y);
if (x == y) {
return;
}
if (siz[x] > siz[y]) {
swap(x, y);
}
st[++tot] = {x, y};
fa[x] = y;
siz[y] += siz[x];
}
void HS(int x) {
for (; tot != x; tot--) {
int x = st[tot].x, y = st[tot].y;
siz[y] -= siz[x], fa[x] = x;
}
}
void solve(int l, int r, int L, int R) {
if (l > r || L > R) {
return;
}
int mid = (l + r) / 2, o = mid - 1;
int cnt = tot;
for (int i = mid; i <= min(r, L - 1); i++) {
int u = a[i].u, v = a[i].v, x = a[i].x, y = a[i].y;
merge(c[u][x], c[v][y]);
merge(c[u][!x], c[v][!y]);
}
int tmp = tot;
for (int i = max(L, mid); i <= R; i++) {
int u = a[i].u, v = a[i].v, x = a[i].x, y = a[i].y;
int ooo = tot;
merge(c[u][x], c[v][y]);
merge(c[u][!x], c[v][!y]);
if (find(c[u][x]) == find(c[u][!x])) {
HS(ooo);
break;
}
o = i;
}
mx[mid] = o;
HS(tmp);
solve(l, mid - 1, L, o);
HS(cnt);
for (int i = max(r + 1, L); i <= o - 1; i++) {
int u = a[i].u, v = a[i].v, x = a[i].x, y = a[i].y;
merge(c[u][x], c[v][y]);
merge(c[u][!x], c[v][!y]);
}
solve(mid + 1, r, o, R);
HS(cnt);
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> m >> q;
for (int i = 1; i <= n + n; i++) {
fa[i] = i;
siz[i] = 1;
}
for (int i = 1; i <= n; i++) {
c[i][0] = i;
c[i][1] = i + n;
}
for (int i = 1, u, x, v, y; i <= m; i++) {
cin >> u >> x >> v >> y;
a[i] = {u, x, v, y};
}
solve(1, m, 1, m);
for (int i = 1; i <= m; i++) {
f[i][0] = mx[i] + 1;
}
f[m + 1][0] = m + 1;
for (int j = 1; j <= 20; j++) {
for (int i = 1; i <= m + 1; i++) {
f[i][j] = f[f[i][j - 1]][j - 1];
}
}
for (int l, r; q--;) {
cin >> l >> r;
int ans = 0;
for (int j = 20; j >= 0; j--) {
if (f[l][j] <= r) {
l = f[l][j];
ans += (1 << j);
}
}
if (l <= r) {
l = f[l][0];
ans++;
}
if (l <= r) {
cout << -1 << "\n";
} else {
cout << ans << "\n";
}
}
return 0;
}