BZOJ 3218: a + b Problem
Posted You Siki
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 3218: a + b Problem相关的知识,希望对你有一定的参考价值。
3218: a + b Problem
Time Limit: 20 Sec Memory Limit: 40 MBSubmit: 1280 Solved: 481
[Submit][Status][Discuss]
Description
用可持久化线段树优化边的数量,跑最小割求答案.
1 #include <cstdio> 2 #include <cstring> 3 4 namespace read 5 { 6 inline char Char(void) 7 { 8 static const int siz = 1 << 20; 9 10 static char buf[siz]; 11 static char *hd = buf + siz; 12 static char *tl = buf + siz; 13 14 if (hd == tl) 15 fread(hd = buf, 1, siz, stdin); 16 17 return *hd++; 18 } 19 20 inline int Int(void) 21 { 22 register int ret = 0, neg = 0, c = Char(); 23 24 for (; c < 48; c = Char()) 25 if (c == ‘-‘)neg ^= true; 26 27 for (; c > 47; c = Char()) 28 ret = ret * 10 + c - ‘0‘; 29 30 return neg ? -ret : ret; 31 } 32 } 33 34 const int inf = 1e9 + 7; 35 36 namespace network 37 { 38 int S, T; 39 int hd[200005]; 40 int to[1000005]; 41 int nt[1000005]; 42 int fl[1000005]; 43 44 inline void add(int u, int v, int f) 45 { 46 static int edge = 0, init = 1; 47 48 if (init)memset(hd, -1, sizeof(hd)), init = 0; 49 50 nt[edge] = hd[u]; to[edge] = v; fl[edge] = f; hd[u] = edge++; 51 nt[edge] = hd[v]; to[edge] = u; fl[edge] = 0; hd[v] = edge++; 52 } 53 54 int dep[200005]; 55 56 inline bool bfs(void) 57 { 58 static int que[200005], l, r; 59 memset(dep, 0, sizeof(dep)); 60 dep[que[l = 0] = S] = r = 1; 61 62 while (l != r) 63 { 64 int u = que[l++], v; 65 66 for (int i = hd[u]; ~i; i = nt[i]) 67 if (fl[i] && !dep[v = to[i]]) 68 dep[que[r++] = v] = dep[u] + 1; 69 } 70 71 return dep[T]; 72 } 73 74 inline int min(const int &a, const int &b) 75 { 76 return a < b ? a : b; 77 } 78 79 int cur[200005]; 80 81 int dfs(int u, int f) 82 { 83 if (u == T || !f) 84 return f; 85 86 int used = 0, flow, v; 87 88 for (int i = cur[u]; ~i; i = nt[i]) 89 if (fl[i] && dep[v = to[i]] == dep[u] + 1) 90 { 91 flow = dfs(v, min(f - used, fl[i])); 92 93 used += flow; 94 fl[i] -= flow; 95 fl[i^1] += flow; 96 97 if (fl[i]) 98 cur[u] = i; 99 100 if (f == used) 101 return f; 102 } 103 104 if (!used) 105 dep[u] = 0; 106 107 return used; 108 } 109 110 inline long long maxFlow(void) 111 { 112 long long maxFlow = 0, newFlow; 113 114 while (bfs()) 115 { 116 memcpy(cur, hd, sizeof(cur)); 117 118 while (newFlow = dfs(S, inf)) 119 maxFlow += newFlow; 120 } 121 122 return maxFlow; 123 } 124 125 inline long long minCut(void) 126 { 127 return maxFlow(); 128 } 129 } 130 131 int pos[5005][2], ID; 132 133 namespace segtree 134 { 135 struct node 136 { 137 int id; 138 int cnt; 139 node *ls; 140 node *rs; 141 }; 142 143 node *root[5005]; 144 145 inline node *newnode(int _cnt, node *_ls, node *_rs) 146 { 147 static node buf[200005], *hd = buf; 148 149 hd->ls = _ls; 150 hd->rs = _rs; 151 hd->id = ++ID; 152 hd->cnt = _cnt; 153 154 return hd++; 155 } 156 157 node *insert(node *f, int l, int r, int pos, int fr) 158 { 159 node *ret; 160 161 if (l == r) 162 ret = newnode(f->cnt + 1, 0, 0); 163 else 164 { 165 int mid = (l + r) >> 1; 166 167 if (pos <= mid) 168 ret = newnode(f->cnt + 1, insert(f->ls, l, mid, pos, fr), f->rs); 169 else 170 ret = newnode(f->cnt + 1, f->ls, insert(f->rs, mid + 1, r, pos, fr)); 171 } 172 173 network::add(fr, ret->id, inf); 174 network::add(f->id, ret->id, inf); 175 176 return ret; 177 } 178 179 void travel(node *t, int l, int r, int x, int y, int to) 180 { 181 if (t->cnt == 0)return; 182 183 if (l == x && r == y) 184 network::add(t->id, to, inf); 185 else 186 { 187 int mid = (l + r) >> 1; 188 189 if (y <= mid) 190 travel(t->ls, l, mid, x, y, to); 191 else if (x > mid) 192 travel(t->rs, mid + 1, r, x, y, to); 193 else 194 { 195 travel(t->ls, l, mid, x, mid, to); 196 travel(t->rs, mid + 1, r, mid + 1, y, to); 197 } 198 } 199 } 200 201 inline void init(void) 202 { 203 memset(root, 0, sizeof(root)); 204 root[0] = newnode(0, 0, 0); 205 root[0]->ls = root[0]; 206 root[0]->rs = root[0]; 207 } 208 } 209 210 signed main(void) 211 { 212 int n = read::Int(); 213 214 long long answer = 0; 215 216 for (int i = 1; i <= n; ++i) 217 pos[i][0] = ++ID, 218 pos[i][1] = ++ID; 219 220 segtree::init(); 221 222 using network::S; 223 using network::T; 224 225 S = 0, T = ++ID; 226 227 for (int i = 1; i <= n; ++i) 228 { 229 using read::Int; 230 using network::add; 231 using segtree::root; 232 using segtree::insert; 233 using segtree::travel; 234 235 int a = Int(); 236 int b = Int(); 237 int w = Int(); 238 int l = Int(); 239 int r = Int(); 240 int p = Int(); 241 242 answer += w; 243 answer += b; 244 245 add(S, pos[i][0], w); 246 add(pos[i][0], T, b); 247 add(pos[i][1], pos[i][0], p); 248 249 static const int mx = 1000000000; 250 251 root[i] = insert(root[i - 1], 0, mx, a, pos[i][0]); 252 travel(root[i - 1], 0, mx, l, r, pos[i][1]); 253 } 254 255 printf("%lld\n", answer - network::minCut()); 256 } 257 /* 258 Sample Input 259 10 260 0 1 7 3 9 2 261 7 4 0 9 10 5 262 1 0 4 2 10 2 263 7 9 1 5 7 2 264 6 3 5 3 6 2 265 6 6 4 1 8 1 266 6 1 6 0 6 5 267 2 2 5 0 9 3 268 5 1 3 0 2 5 269 5 6 7 1 1 2 270 271 Sample Output 272 55 273 */
@Author: YouSiki
以上是关于BZOJ 3218: a + b Problem的主要内容,如果未能解决你的问题,请参考以下文章