# BZOJ 4025: 二分图

## 4025: 二分图

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 870  Solved: 333
[Submit][Status][Discuss]

3 3 3
1 2 0 2
2 3 0 3
1 3 1 2

Yes
No
Yes

## HINT

0时刻，出现两条边1-2和2-3。

1时刻，出现一条边1-3。

2时刻，1-2和1-3两条边消失。

n<=100000，m<=200000，T<=100000，1<=u,v<=n，0<=start<=end<=T。

## Source

[Submit][Status][Discuss]

CDQ分治 + 可回溯的并查集

 1 #include <bits/stdc++.h>
2   const int siz = 2000005;
3   int n, m, tim, fa[siz], sz[siz], bk[siz], tot, ans[siz];
4   struct edge { int x, y, s, t; }e[siz];
5   inline bool cmp1(const edge &a, const edge &b) {
6     return a.s == b.s ? a.t < b.t : a.s < b.s;
7 } inline bool cmp2(const edge &a, const edge &b) {
8     return a.t == b.t ? a.s < b.s : a.t < b.t;
9 } inline int find(int u) {
10     while (fa[u] != u)u = fa[u]; return u;
11 } inline void add(int a, int b) {
12     int A = find(a), B = find(b);
13     if (sz[A] > sz[B])fa[B] = A, sz[A] += sz[B], bk[++tot] = B;
14     else fa[A] = B, sz[B] += sz[A], bk[++tot] = A;
15 } inline bool adde(int a, int b) {
16     --a, --b; add(a << 1, b << 1 | 1), add(a << 1 | 1, b << 1); return find(a << 1) == find(a << 1 | 1);
17 } inline void rec(int a) {
18     sz[fa[a]] -= sz[a]; fa[a] = a;
19 } void solve(int L, int R, int l, int r) {
20     for (int i = l; i <= r; ++i)if (e[i].s <= L && e[i].t >= R) { if (adde(e[i].x, e[i].y)) {
21         for (int j = L; j <= R; ++j)ans[j] = 1; return; } else std::swap(e[i--], e[r--]); }
22     if (L == R)return; int top = tot, mid = (L + R) >> 1;
23     { std::sort(e + l, e + r + 1, cmp1); int t = l; while (t <= r && e[t].s <= mid)++t; solve(L, mid, l, t - 1); while (tot > top)rec(bk[tot--]); }
24     { std::sort(e + l, e + r + 1, cmp2); int t = r; while (t >= l && e[t].t >= mid + 1)--t; solve(mid + 1, R, t + 1, r); while (tot > top)rec(bk[tot--]); }
25 } signed main(void) {
26     scanf("%d%d%d", &n, &m, &tim);
27     for (int i = 1; i <= 2 * n; ++i)fa[i] = i, sz[i] = 1;
28     for (int i = 1; i <= m; ++i)scanf("%d%d%d%d", &e[i].x, &e[i].y, &e[i].s, &e[i].t), ++e[i].s;
29     solve(1, tim, 1, m); for (int i = 1; i <= tim; ++i)puts(ans[i] ? "No" : "Yes");
30 }

@Author: YouSiki

posted @ 2017-01-11 12:08  YouSiki  阅读(224)  评论(0编辑  收藏  举报