# 【离线 线段树分治】bzoj4025: 二分图

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。

## 题目分析

 1 #include<bits/stdc++.h>
2 const int maxn = 100035;
3 const int maxm = 200035;
4 const int maxt = 100035;
5 const int maxOpt = 200035;
6
7 int n,m,T;
8 struct Edge
9 {
10     int u,v,s,t;
11     Edge(int a=0, int b=0, int c=0, int d=0):u(a),v(b),s(c),t(d) {}
12 }tmp;
13 typedef std::vector<Edge> vec;
14 struct Dsu
15 {
16     int top,fat[maxn],size[maxn],d[maxn];
17     std::pair<int, int> stk[maxOpt];
18     void init(){for (int i=1; i<=n; i++) fat[i] = i, size[i] = 1;}
19     int find(int x){while (x!=fat[x]) x = fat[x];return x;}
20     int get(int x){int ret = 0;while(x!=fat[x]) ret ^= d[x], x = fat[x];return ret;}
21     bool merge(int x, int y)
22     {
23         int fx = find(x), fy = find(y);
24         if (fx==fy) return get(x)^get(y)^1;
25         if (size[fx] > size[fy]) std::swap(fx, fy);
26         fat[fx] = fy, size[fy] += size[fx];
27         d[fx] = get(x)^get(y)^1;
28         stk[++top] = std::make_pair(fx, fy);
29         return 0;
30     }
31     void cancel()
32     {
33         int x = stk[top].first, y = stk[top].second;
34         fat[x] = x, size[y] -= size[x], --top, d[x] = 0;
35     }
36 }dsu;
37 bool ans[maxt];
38 vec opt;
39
41 {
42     char ch = getchar();
43     int num = 0, fl = 1;
44     for (; !isdigit(ch); ch=getchar())
45         if (ch=='-') fl = -1;
46     for (; isdigit(ch); ch=getchar())
47         num = (num<<1)+(num<<3)+ch-48;
48     return num*fl;
49 }51 void solve(int l, int r, vec opt)
52 {
53     vec L,R;
54     int mid = (l+r)>>1, tmp = dsu.top;
55     for (int i=0, mx=opt.size(); i<mx; i++)
56     {
57         int s = opt[i].s, t = opt[i].t;
58         if (s <= l&&r <= t){
59             if (dsu.merge(opt[i].u, opt[i].v)){
60                 while (tmp!=dsu.top) dsu.cancel();
61                 return;
62             }
63         }else{
64             if (s <= mid) L.push_back(opt[i]);
65             if (t > mid) R.push_back(opt[i]);
66         }
67     }
68     if (l==r) ans[l] = 1;
69     else solve(l, mid, L), solve(mid+1, r, R);
70     while (tmp!=dsu.top) dsu.cancel();
71 }
72 int main()
73 {
75     for (int i=1; i<=m; i++)
76     {
78         if (tmp.s <= tmp.t) opt.push_back(tmp);
79     }
80     solve(1, T, opt);
81     for (int i=1; i<=T; i++) puts(ans[i]?"Yes":"No");
82     return 0;
83 }

END

posted @ 2019-01-12 11:21  AntiQuality  阅读(149)  评论(0编辑  收藏  举报