码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ3218 a + b Problem

时间:2015-01-30 21:01:48      阅读:256      评论:0      收藏:0      [点我收藏+]

标签:

vfk我给您跪下了。。。主席树优化网络流建图>.<

再次Orz PoPoQQQ(最近懒得写题解了。。)

 

技术分享
  1 /**************************************************************
  2     Problem: 3218
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:3084 ms
  7     Memory:29732 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <algorithm>
 13  
 14 #define p1(i) i * 2 - 1
 15 #define p2(i) i * 2
 16 using namespace std;
 17 typedef long long ll;
 18 const int N = 5005;
 19 const int N1 = 200005;
 20 const int M = N1 * 10;
 21 const int inf = 1e9;
 22  
 23 struct edge {
 24   int next, to, f;
 25   edge() {}
 26   edge(int _n, int _t, int _f) : next(_n), to(_t), f(_f) {}
 27 } e[M];
 28  
 29 struct seg_node {
 30   seg_node *ls, *rs;
 31   int cnt, w;
 32 } *seg[N], mempool[N1], *cnt_seg = mempool;
 33  
 34 int n, cnt_p, S, T;
 35 int first[N1], tot = 1;
 36 int d[N1], q[N1];
 37 ll ans;
 38  
 39 int read() {
 40   int x = 0;
 41   char ch = getchar();
 42   while (ch < 0 || 9 < ch)
 43     ch = getchar();
 44   while (0 <= ch && ch <= 9)
 45     (x *= 10) += ch - 0, ch = getchar();
 46   return x;
 47 }
 48  
 49 inline void add_edges(int x, int y, int z) {
 50   e[++tot] = edge(first[x], y, z), first[x] = tot;
 51   e[++tot] = edge(first[y], x, 0), first[y] = tot;
 52 }
 53  
 54 #define y e[x].to
 55 #define p q[l]
 56 bool bfs() {
 57   int l, r, x;
 58   memset(d, -1, sizeof(d));
 59   d[q[1] = S] = 1;
 60   for (l = r = 1; l != r + 1; ++l)
 61     for (x = first[p]; x; x = e[x].next)
 62       if (!~d[y] && e[x].f) {
 63     d[q[++r] = y] = d[p] + 1;
 64     if (y == T) return 1;
 65       }
 66   return 0;
 67 }
 68 #undef p
 69  
 70 int dfs(int p, int lim) {
 71   if (p == T || !lim) return lim;
 72   int x, tmp, rest = lim;
 73   for (x = first[p]; x && rest; x = e[x].next) 
 74     if (d[y] == d[p] + 1 && ((tmp = min(e[x].f, rest)) > 0)) {
 75       rest -= (tmp = dfs(y, tmp));
 76       e[x].f -= tmp, e[x ^ 1].f += tmp;
 77       if (!rest) return lim;
 78     }
 79   if (rest) d[p] = -1;
 80   return lim - rest;
 81 }
 82 #undef y
 83  
 84 ll Dinic() {
 85   ll res = 0;
 86   while (bfs())
 87     res += dfs(S, inf);
 88   return res;
 89 }
 90  
 91  
 92 #define mid (l + r >> 1)
 93 void seg_insert(seg_node *&p, int l, int r, int pos, int from) {
 94   add_edges(from, cnt_p + 1, inf), add_edges(p -> w, cnt_p + 1, inf);
 95   *(++cnt_seg) = *p, p = cnt_seg;
 96   ++(p -> cnt), p -> w = ++cnt_p;
 97   if (l == r) return;
 98   if (pos <= mid) seg_insert(p -> ls, l, mid, pos, from);
 99   else seg_insert(p -> rs, mid + 1, r, pos, from);
100 }
101  
102 void seg_work(seg_node *p, int l, int r, int L, int R, int to) {
103   if (!(p -> cnt)) return;
104   if (l == L && R == r) {
105     add_edges(p -> w, to, inf);
106     return;
107   }
108   if (R <= mid) seg_work(p -> ls, l, mid, L, R, to);
109   else if (mid < L) seg_work(p -> rs, mid + 1, r, L, R, to);
110   else seg_work(p -> ls, l, mid, L, mid, to), seg_work(p -> rs, mid + 1, r, mid + 1, R, to);
111 }
112 #undef mid
113  
114 int main() {
115   int i, a, b, w, l, r, p;
116   n = read(), S = n << 1 | 1, T = cnt_p = S + 1;
117   seg[0] = ++cnt_seg;
118   seg[0] -> ls = seg[0] -> rs = seg[0];
119   for (i = 1; i <= n; ++i) {
120     a = read(), b = read(), w = read(), l = read(), r = read(), p = read();
121     add_edges(S, p1(i), w), add_edges(p1(i), T, b);
122     seg_insert(seg[i] = seg[i - 1], 0, inf, a, p1(i));
123     seg_work(seg[i - 1], 0, inf, l, r, p2(i));
124     add_edges(p2(i), p1(i), p);
125     ans += w + b;
126   }
127   printf("%lld\n", ans - Dinic());
128   return 0;
129 }
View Code

 

BZOJ3218 a + b Problem

标签:

原文地址:http://www.cnblogs.com/rausen/p/4263094.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!