G. Oleg and chess
先考虑网络流。。。是最朴素的二分图匹配。。。
还是设法要减少边的规模。。。我们类比扫描线来做矩形合并。。
从左到右扫描每一列,我们用函数式线段树,就能维护出代表这一列的线段树的根节点状态。。
那么只要从源点向根节点连过去一条容量为 1 的边即可。。注意需要保证这些线段树共享同一组闭合状态。。。
总感觉有更好的做法。。。
const int N = int(1e4) + 9;
int T[N], H[N]; VI adj[N];
int n, m;
namespace Chairman_Tree {
#define lx c[0][x]
#define rx c[1][x]
#define ly c[0][y]
#define ry c[1][y]
#define lz c[0][z]
#define rz c[1][z]
#define ml ((l+r)>>1)
#define mr (ml+1)
#define lc lx, l, ml
#define rc rx, mr, r
const int NN = 100*N;
int c[2][NN]; int tot;
int pp; int dd;
int new_node() {
return ++tot;
}
int new_node(int y) {
int x = ++tot; lx = ly; rx = ry;
return x;
}
void Build(int& x, int l, int r) {
if (l == r) {
x = l;
} else {
x = new_node();
Build(lc);
Build(rc);
}
}
int Insert(int x, int l, int r, int y, int a, int b) {
if (b < l || r < a) return x;
if (a <= l && r <= b) {
return y;
} else {
x = new_node(x);
lx = Insert(lc, ly, a, b);
rx = Insert(rc, ry, a, b);
return x;
}
}
} using namespace Chairman_Tree;
VII del[N], add[N];
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("/Users/minakokojima/Documents/GitHub/ACM-Training/Workspace/out.txt", "w", stdout);
#endif
RD(n); Rush {
int x1, y1, x2, y2; RD(x1, y1, x2, y2); ++x2;
add[x1].PB({y1, y2});
del[x2].PB({y1, y2});
}
atcoder::mf_graph<int> G(NN);
int s = 0, t = n+1; REP_1(i, n) G.add_edge(i, t, 1);
tot = t;
int x; Build(x, 1, n); int o = x, a = 0; REP_1(i, n) {
int y = x;
for (auto e: del[i]) x = Insert(x, 1, n, o, e.fi, e.se);
for (auto e: add[i]) x = Insert(x, 1, n, 0, e.fi, e.se);
if (x != y) {
if (y && a) G.add_edge(s, y, a);
a = 0;
}
++a;
}
if (x) G.add_edge(s, x, a);
FOR_1(x, t+1, tot) {
if (lx) G.add_edge(x, lx, INF);
if (rx) G.add_edge(x, rx, INF);
}
cout << G.flow(s, t) << endl;
}




Alca
Amber
Belleve Invis
Chensiting123
Edward_mj
Fotile96
Hlworld
Kuangbin
Liyaos
Lwins
LYPenny
Mato 完整版
Mikeni2006
Mzry
Nagatsuki
Neko13
Oneplus
Rukata
Seter
Sevenkplus
Sevenzero
Shirleycrow
Vfleaking
wangzhpp
Watashi
WJMZBMR
Wywcgs
XadillaX
Yangzhe
三途川玉子
About.me
Vijos
