飘扬的旗帜
我也不知道哪里蒯來的題。反正二分 + 2-sat + 線段樹優化連邊就完事了。
注意答案可能為0..
1 #include <bits/stdc++.h>
2
3 const int N = 100010;
4
5 struct Edge {
6 int nex, v;
7 }edge[3000010]; int tp;
8
9 struct Node {
10 int x, f;
11 Node(int X = 0, int F = 0) {
12 x = X;
13 f = F;
14 }
15 };
16
17 int e[N], num, dfn[N], low[N], X[N], xx, tot, n, fr[N], scc_cnt, ls[N], rs[N];
18 std::vector<Node> v[N];
19 int stk[N], top, rt, A[N], B[N];
20
21 inline void add(int x, int y) {
22 tp++;
23 edge[tp].v = y;
24 edge[tp].nex = e[x];
25 e[x] = tp;
26 return;
27 }
28
29 inline void clear() {
30 memset(e + 1, 0, tot * sizeof(int));
31 memset(dfn + 1, 0, tot * sizeof(int));
32 memset(fr + 1, 0, tot * sizeof(int));
33 tp = top = num = scc_cnt = 0;
34 return;
35 }
36
37 void tarjan(int x) {
38 low[x] = dfn[x] = ++num;
39 stk[++top] = x;
40 for(int i = e[x]; i; i = edge[i].nex) {
41 int y = edge[i].v;
42 if(!dfn[y]) {
43 tarjan(y);
44 low[x] = std::min(low[x], low[y]);
45 }
46 else if(!fr[y]) {
47 low[x] = std::min(low[x], dfn[y]);
48 }
49 }
50 if(low[x] == dfn[x]) {
51 ++scc_cnt;
52 int y;
53 do {
54 y = stk[top];
55 top--;
56 fr[y] = scc_cnt;
57 } while(y != x);
58 }
59 return;
60 }
61
62 void Add(int L, int R, int v, int l, int r, int &o) {
63 if(!o) o = ++tot;
64 if(L <= l && r <= R) {
65 add(v, o);
66 return;
67 }
68 int mid = (l + r) >> 1;
69 if(L <= mid) Add(L, R, v, l, mid, ls[o]);
70 if(mid < R) Add(L, R, v, mid + 1, r, rs[o]);
71 return;
72 }
73
74 void build(int f, int l, int r, int &o) {
75 if(!o) o = ++tot;
76 if(f) add(f, o);
77 if(l == r) {
78 for(int i = 0; i < (int)v[r].size(); i++) {
79 if(v[r][i].f) {
80 add(o, v[r][i].x);
81 }
82 else {
83 add(o, v[r][i].x + n);
84 }
85 }
86 return;
87 }
88 int mid = (l + r) >> 1;
89 build(o, l, mid, ls[o]);
90 build(o, mid + 1, r, rs[o]);
91 return;
92 }
93
94 inline bool check(int k) {
95
96 clear();
97 for(int i = 1; i <= n; i++) {
98 int l = std::lower_bound(X + 1, X + xx + 1, X[A[i]] - k) - X;
99 int r = std::upper_bound(X + 1, X + xx + 1, X[A[i]] + k) - X - 1;
100 int mid = A[i];
101 if(l < mid) {
102 Add(l, mid - 1, i, 1, xx, rt);
103 }
104 if(mid < r) {
105 Add(mid + 1, r, i, 1, xx, rt);
106 }
107 for(int j = 0; j < (int)v[mid].size(); j++) {
108 if(v[mid][j].x == i) continue;
109 if(v[mid][j].f) {
110 add(i, v[mid][j].x);
111 }
112 else {
113 add(i, v[mid][j].x + n);
114 }
115 }
116 l = std::lower_bound(X + 1, X + xx + 1, X[B[i]] - k) - X;
117 r = std::upper_bound(X + 1, X + xx + 1, X[B[i]] + k) - X - 1;
118 mid = B[i];
119 if(l < mid) {
120 Add(l, mid - 1, i + n, 1, xx, rt);
121 }
122 if(mid < r) {
123 Add(mid + 1, r, i + n, 1, xx, rt);
124 }
125 for(int j = 0; j < (int)v[mid].size(); j++) {
126 if(v[mid][j].x == i) continue;
127 if(v[mid][j].f) {
128 add(i + n, v[mid][j].x);
129 }
130 else {
131 add(i + n, v[mid][j].x + n);
132 }
133 }
134 }
135 build(0, 1, xx, rt);
136 for(int i = 1; i <= tot; i++) {
137 if(!dfn[i]) {
138 tarjan(i);
139 }
140 }
141 for(int i = 1; i <= n; i++) {
142 if(fr[i] == fr[i + n]) return 0;
143 }
144 return 1;
145 }
146
147 int main() {
148
149 scanf("%d", &n);
150 tot = n << 1;
151 for(int i = 1; i <= n; i++) {
152 scanf("%d%d", &A[i], &B[i]);
153 X[++xx] = A[i]; X[++xx] = B[i];
154 }
155 std::sort(X + 1, X + xx + 1);
156 xx = std::unique(X + 1, X + xx + 1) - X - 1;
157 for(int i = 1; i <= n; i++) {
158 A[i] = std::lower_bound(X + 1, X + xx + 1, A[i]) - X;
159 B[i] = std::lower_bound(X + 1, X + xx + 1, B[i]) - X;
160 v[A[i]].push_back(Node(i, 0));
161 v[B[i]].push_back(Node(i, 1));
162 }
163
164 int l = -1, r = X[xx] - X[1];
165 while(l < r) {
166 int mid = (l + r + 1) >> 1;
167 if(check(mid)) {
168 l = mid;
169 }
170 else {
171 r = mid - 1;
172 }
173 }
174
175 printf("%d
", r + 1);
176 return 0;
177 }
AC代碼
我這個寫法不對,如果離散化了就不能暴力處理單個位置的其他邊,因為可能會被卡成n2。正確的方法是不離散化或者對每個位置再用一個前后綴優化連邊。
總結
- 上一篇: 用NI的数据采集卡实现简单电子测试之6—
- 下一篇: DFT测试-OCC电路介绍