「BalticOI 2020」小丑
Posted zqs2020
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「BalticOI 2020」小丑相关的知识,希望对你有一定的参考价值。
预处理出 \\(f_i\\) 表示最大的使得在加入所有 \\([1,i)\\or [j,m]\\) 中的边后存在奇环的最大 \\(j\\)。
显然 \\(f\\) 满足单调性,于是可以整体二分。
对于分治区间 \\([l,r]\\),已知所有 \\(\\f_l...f_r\\\\in [x,y]\\),那么暴力计算出 \\(f_mid\\),然后递归分治。
暴力计算时用并查集判断奇环即可。需要支持回撤操作,所以使用可撤销并查集。
注意: 由于存在 \\([1,i)\\) 中的边已经构成奇环的特殊情况,在 \\(x=y\\) 时不能直接 return!
#include <cstdio>
#include <algorithm>
#define gc (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 65536, stdin), p1 == p2) ? EOF : *p1 ++)
char buf[65536], *p1, *p2;
inline int read()
int x = 0;
char ch;
while ((ch = gc) < 48);
do x = x * 10 + ch - 48; while ((ch = gc) >= 48);
return x;
struct node int x, y; stk[200005];
int fa[200005], from[200005], to[200005], dis[200005], sze[200005], f[200005], n, m, q, top;
node getval(int x)
int sum = 0;
while (fa[x] != x) sum ^= dis[x], x = fa[x];
return nodex, sum;
inline bool merge(int x, int y)
node fx = getval(x), fy = getval(y), tmp;
if (fx.x == fy.x) return fx.y == fy.y;
if (sze[fx.x] < sze[fy.x]) tmp = fx, fx = fy, fy = tmp;
fa[fy.x] = fa[fx.x], dis[fy.x] = fx.y ^ fy.y ^ 1, sze[fx.x] += sze[fy.x];
stk[++ top] = nodefx.x, fy.x; return false;
void rollback(int x)
while (top > x) fa[stk[top].y] = stk[top].y, sze[stk[top].x] -= sze[stk[top].y], dis[stk[top].y] = 0, -- top;
void solve(int l, int r, int x, int y)
if (l > r || x > y) return;
int mid = l + r >> 1, now = top;
bool flag = false;
for (int i = l; i < mid; ++ i) flag |= merge(from[i], to[i]);
if (flag)
for (int i = mid; i <= r; ++ i) f[i] = m + 1;
rollback(now), solve(l, mid - 1, x, y);
return;
int suftop = top;
for (int i = y; i >= x && i >= mid; -- i)
if (flag |= merge(from[i], to[i])) f[mid] = i; break;
rollback(suftop);
if (merge(from[mid], to[mid])) for (int i = mid + 1; i <= r; ++ i) f[i] = m + 1;
else solve(mid + 1, r, f[mid], y);
rollback(now), now = top;
for (int i = y; i > f[mid]; -- i) merge(from[i], to[i]);
solve(l, mid - 1, x, f[mid]);
rollback(now);
int main()
n = read(), m = read(), q = read();
for (int i = 1; i <= n; ++ i) fa[i] = i, sze[i] = 1;
for (int i = 1; i <= m; ++ i) from[i] = read(), to[i] = read();
solve(1, m, 1, m);
for (int i = 1, l, r; i <= q; ++ i) l = read(), r = read(), puts(r < f[l] ? "YES" : "NO");
return 0;
以上是关于「BalticOI 2020」小丑的主要内容,如果未能解决你的问题,请参考以下文章
[BalticOI 2014]Three Friends 题解