BZOJ - 3218 A+B Problem
首先如果我们不考虑奇怪的点的话,这道题就是一个很显然的最小割了。
建图也很显然:$<s,i,w_i> \; <i,t,b_i> \; ANS = \sum_i{b_i+w_i}-\mbox{maxflow}$
加入奇怪的点:$<i',i,p_i> \; <j, i', \infty>$其中$j<i \wedge l_i \leqslant a_j \lesqslant r_i$
但是这样直接建图的话边数会爆炸,所以我们用线段树优化建图。由于$j<i$这个限制,要用到可持久化线段树。
写给自己:网络流ecnt=1!!!
1 #include<bits/stdc++.h> 2 const int INF = 1e9; 3 using namespace std; 4 #define nc getchar 5 inline void read(int &x) { 6 char b = nc(); x = 0; 7 for (; !isdigit(b); b = nc()); 8 for (; isdigit(b); b = nc()) x = x * 10 + b - '0'; 9 } 10 const int N = 5005, M = 150005; 11 struct Edge { 12 int v, c, n; 13 } E[1500000]; 14 int ecnt = 1, d[M], cur[M], _s, _t, head[M]; 15 int tot; 16 inline void aE(int u, int v, int c) { 17 E[++ecnt] = (Edge){v, c, head[u]}; head[u] = ecnt; 18 } 19 inline void ae(int u, int v, int c) { 20 if (u == 0 || v == 0) return ; 21 aE(u, v, c); aE(v, u, 0); 22 } 23 bool bfs() { 24 for (int i = 1; i <= tot; ++i) d[i] = 0; 25 d[_s] = 1; queue < int > q; q.push(_s); 26 while (!q.empty()) { 27 int u = q.front(); q.pop(); 28 for(int i = head[u]; i; i = E[i].n) { 29 if (!d[E[i].v] && E[i].c > 0) { 30 d[E[i].v] = d[u] + 1; 31 q.push(E[i].v); 32 if (E[i].v == _t) return true; 33 } 34 } 35 } 36 return false; 37 } 38 int dfs(int u, int a) { 39 if (u == _t || a == 0) return a; 40 int flow = 0, f; 41 for (int &i = cur[u]; i; i = E[i].n) { 42 if (d[E[i].v] == d[u] + 1 && (f = dfs(E[i].v, min(a, E[i].c))) > 0) { 43 flow += f; 44 E[i].c -= f; 45 E[i^1].c += f; 46 a -= f; 47 if (!a) break; 48 } 49 } 50 return flow; 51 } 52 int dinic() { 53 int flow = 0; 54 while (bfs()) { 55 for (int i = 1; i <= tot; ++i) 56 cur[i] = head[i]; 57 flow += dfs(_s, INF); 58 } 59 return flow; 60 } 61 int n, a[N], b[N], w[N], l[N], r[N], p[N], v[N*3], H; 62 inline int idx(int x) { 63 return lower_bound(v + 1, v + 1 + H, x) - v; 64 } 65 struct Node { 66 Node *ch[2]; int id; 67 } mem[N*16], *rt[N], *C = mem, Tnull, *null = &Tnull; 68 inline Node* newNode(int v, Node *p) { 69 C->ch[0] = p->ch[0]; C->ch[1] = p->ch[1]; 70 C->id = v; return C++; 71 } 72 #define lson l, m, t->ch[0] 73 #define rson m + 1, r, t->ch[1] 74 void insert(Node *&p, int x, int po, int l, int r, Node *&t) { 75 t = newNode(++tot, p); 76 if (l == r) return ae(x, t->id, INF), ae(p->id, t->id, INF); 77 int m = (l + r) >> 1; 78 if (po <= m) { 79 insert(p->ch[0], x, po, lson); 80 } else { 81 insert(p->ch[1], x, po, rson); 82 } 83 ae(t->ch[0]->id, t->id, INF); 84 ae(t->ch[1]->id, t->id, INF); 85 } 86 void link(int x, int L, int R, int l, int r, Node *&t) { 87 if (t == null) return; 88 if (L <= l && r <= R) 89 return ae(t->id, x, INF); 90 int m = (l + r) >> 1; 91 if (L <= m) link(x, L, R, lson); 92 if (m < R) link(x, L, R, rson); 93 } 94 int main() { 95 null->ch[0] = null->ch[1] = null; 96 read(n); int ans = 0; 97 for (int i = 0; i <= n; ++i) rt[i] = null; 98 _s = n + n + 1, _t = _s + 1; tot = _t; 99 for (int i = 1; i <= n; ++i) { 100 read(a[i]); read(b[i]); read(w[i]); 101 read(l[i]); read(r[i]); read(p[i]); 102 v[++H] = a[i]; v[++H] = l[i]; v[++H] = r[i]; 103 ans += w[i] + b[i]; 104 if (l[i] > r[i]) swap(l[i], r[i]); 105 } 106 sort(v + 1, v + 1 + H); 107 H = unique(v + 1, v + 1 + H) - v - 1; 108 for (int i = 1; i <= n; ++i) { 109 a[i] = idx(a[i]); l[i] = idx(l[i]); r[i] = idx(r[i]); 110 ae(_s, i, w[i]); ae(i, _t, b[i]); ae(i + n, i, p[i]); 111 } 112 for (int i = 1; i <= n; ++i) { 113 link(i + n, l[i], r[i], 1, H, rt[i-1]); 114 insert(rt[i-1], i, a[i], 1, H, rt[i]); 115 } 116 printf("%d\n", ans - dinic()); 117 return 0; 118 }