【题目链接】

http://www.lydsy.com/JudgeOnline/problem.php?id=3218

【题意】

给n个格子涂白或黑色,白则wi,黑则bi的好看度,若黑格i存在:

1<=j<I,li<=aj<=ri,格子为白色

则损失pi,问最大的好看度。

【思路】

考虑建立最小割模型:

  1. 首先将一个点拆成两个中间连pi
  2. 连边(S,Xi,wi) (Xi,T,bi)
  3. 对于一个满足i要求的j,连边(Xj,Yi,inf),代表i只有两种选择,一为设白色,一为损失pi。

  这样跑出的最小割即为答案。

  但该图的边数过多,因此需要优化。

  建一棵线段树,由线段树中所有被[li,ri]包含的点向Yi连边inf,由Xi向对应的叶子连边。然后加上j<i的条件,我们需要一棵可持久化线段树,因此需要Yi被T[i-1]的[li,ri]区间连边,Xi向T[i]的叶子连边。这样就成功将边数缩到O(nlogn)级别。

【代码】

 #include<set>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define X(i) (i)
#define Y(i) (i+n)
#define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; typedef long long ll;
const int N = 2e5+;
const int inf = 1e9; ll read() {
char c=getchar();
ll f=,x=;
while(!isdigit(c)) {
if(c=='-') f=-; c=getchar();
}
while(isdigit(c))
x=x*+c-'',c=getchar();
return x*f;
} struct Edge {
int u,v,cap,flow;
};
struct Dinic {
int d[N],cur[N],vis[N];
vector<Edge> es;
vector<int> g[N];
queue<int> q; void AddEdge (int u,int v,int w) {
es.push_back((Edge){u,v,w,});
es.push_back((Edge){v,u,,});
int m=es.size();
g[u].push_back(m-);
g[v].push_back(m-);
}
bool bfs(int s,int t) {
memset(vis,,sizeof(vis));
d[s]=; vis[s]=;
q.push(s);
while(!q.empty()) {
int u=q.front(); q.pop();
FOR(i,,(int)g[u].size()-) {
Edge& e=es[g[u][i]];
int v=e.v;
if(e.cap>e.flow&&!vis[v]) {
vis[v]=;
d[v]=d[u]+;
q.push(v);
}
}
}
return vis[t];
}
int dfs(int u,int a,int t) {
if(u==t||a==) return a;
int flow=,f;
for(int& i=cur[u];i<g[u].size();i++) {
Edge& e=es[g[u][i]];
int v=e.v;
if(d[v]==d[u]+&&(f=dfs(v,min(a,e.cap-e.flow),t))>) {
e.flow+=f;
es[g[u][i]^].flow-=f;
flow+=f,a-=f;
if(!a) break;
}
}
return flow;
}
int maxflow(int s,int t) {
int flow=;
while(bfs(s,t)) {
memset(cur,,sizeof(cur));
flow+=dfs(s,inf,t);
}
return flow;
}
} dc; int n,cnt; struct Tnode {
Tnode *ls,*rs;
int sum,id;
void * operator new (size_t,Tnode* l,Tnode* r) {
static Tnode mempool[N],*G=mempool;
G->ls=l,G->rs=r,G->id=++cnt;
return G++;
}
Tnode* build(int l,int r,int x,int from) {
int mid=l+r>>;
Tnode *t;
if(l==r)
t=new (0x0,0x0)Tnode;
else if(x<=mid)
t=new (ls->build(l,mid,x,from),rs) Tnode;
else
t=new (ls,rs->build(mid+,r,x,from)) Tnode;
dc.AddEdge(from,t->id,inf);
dc.AddEdge(id,t->id,inf);
return t;
}
void Add(int l,int r,int L,int R,int to) {
if(L<=l&&r<=R) {
dc.AddEdge(id,to,inf);
} else {
int mid=l+r>>;
if(L<=mid&&ls) ls->Add(l,mid,L,R,to);
if(mid<R&&rs) rs->Add(mid+,r,L,R,to);
}
} } *T[]; int hash[N],tot,a[N],b[N],l[N],r[N],p[N],w[N]; int main()
{
n=read();
cnt=Y(n);
int s=++cnt,t=++cnt;
T[]=new (0x0,0x0)Tnode;
T[]->ls=T[]->rs=T[];
ll ans=;
FOR(i,,n) {
a[i]=read(),b[i]=read(),w[i]=read(),l[i]=read(),r[i]=read(),p[i]=read();
hash[++tot]=a[i],hash[++tot]=l[i],hash[++tot]=r[i];
} sort(hash+,hash+tot+);
tot=unique(hash+,hash+tot+)-hash-;
FOR(i,,n) {
a[i]=lower_bound(hash+,hash+tot+,a[i])-hash;
l[i]=lower_bound(hash+,hash+tot+,l[i])-hash;
r[i]=lower_bound(hash+,hash+tot+,r[i])-hash;
} FOR(i,,n) {
ans+=w[i]+b[i];
dc.AddEdge(s,X(i),w[i]);
dc.AddEdge(X(i),t,b[i]);
T[i]=T[i-]->build(,tot,a[i],X(i));
T[i-]->Add(,tot,l[i],r[i],Y(i));
dc.AddEdge(Y(i),X(i),p[i]);
}
ans-=dc.maxflow(s,t);
printf("%lld\n",ans);
return ;
}

P.S.神的我无力吐槽=-=

bzoj 3218 a + b Problem(最小割+主席树)的更多相关文章

  1. BZOJ3218 UOJ#77 A+B Problem(最小割+主席树)

    竟然在BZOJ上拿了Rank1太给力啦. p.s.:汗,一发这个就被一堆人在2月27号强势打脸-- 传送门(BZOJ) 传送门(UOJ) 说说这道题目吧: 首先是说说这个构图吧.因为有选择关系,我们很 ...

  2. 【bzoj3218】a+b Problem 最小割+主席树

    数据范围:$n≤5000$,$a,l,r≤10^9$,$b,w,p≤2\times 10^5$. 我们考虑一种暴力的最小割做法: 首先令$sum=\sum\limits_{i=1}^{n} b_i+w ...

  3. BZOJ.3218.a + b Problem(最小割ISAP 可持久化线段树优化建图)

    BZOJ UOJ 首先不考虑奇怪方格的限制,就是类似最大权闭合子图一样建图. 对于奇怪方格的影响,显然可以建一条边\((i\to x,p_i)\),然后由\(x\)向\(1\sim i-1\)中权值在 ...

  4. bzoj3218 a+b Problem(最小割+主席树优化建边)

    由于6.22博主要学测,大半时间学文化课,近期刷题量&写题解的数量会急剧下降. 这题出得挺经典的,首先一眼最小割,考虑朴素的做法:与S联通表示白色,与T联通表示黑色,S向i连流量为w[i]的边 ...

  5. BZOJ 3218 A + B Problem (可持久化线段树+最小割)

    做法见dalao博客 geng4512的博客, 思路就是用线段树上的结点来进行区间连边.因为有一个只能往前面连的限制,所以还要可持久化.(duliu) 一直以来我都是写dinicdinicdinic做 ...

  6. [BZOJ 3218] A + B Problem 【可持久化线段树 + 网络流】

    题目连接:BZOJ - 3218 题目分析 题目要求将 n 个点染成黑色或白色,那么我们可以转化为一个最小割模型. 我们规定一个点 i 最后属于 S 集表示染成黑色,属于 T 集表示染成白色,那么对于 ...

  7. 【BZOJ-3218】a+b Problem 最小割 + 可持久化线段树

    3218: a + b Problem Time Limit: 20 Sec  Memory Limit: 40 MBSubmit: 1320  Solved: 498[Submit][Status] ...

  8. [BZOJ 3218]a + b Problem

    又是一道主席树优化网络流的好题 按约大爷的教导,源点为白,汇点为黑,搞成最小割 发现暴力连边要爆炸,但是要连的点在线段树中都构成了一个区间,果断主席树优化之 为什么不用一般线段树? 因为要满足 j&l ...

  9. BZOJ 2007 海拔(平面图最小割-最短路)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2007 题意:给出一个n*n的格子,那么顶点显然有(n+1)*(n+1)个.每两个相邻顶点 ...

随机推荐

  1. eclipse的设置和优化

    转载:http://my.oschina.net/zhaoqian/blog/66545 1.eclipse下的编码设置: eclipse 中使用模板新建 JSP,xhtml等 文件时,默认的编码为: ...

  2. 分布式内存对象缓存系统Memcached-概述

    全面掌握Memcached 1.       概述 Memcached是danga.com(运营LiveJournal的技术团队)开发的一套分布式内存对象缓存系统,是为了加快网站http://www. ...

  3. 核心思想:百度网盘怎么盈利(互联网的高速更新决定了:亏钱你还有点机会,放弃连门都进不了),战略预备队 good

    百度做网盘很大程度就是为了防止别人依靠网盘做大和积累点技术储备.腾讯邮箱怎么赚钱?腾讯影音怎么赚钱?互联网的高速更新决定了,一些你看不起眼的软件很可能就会席卷整个市场,所以互联网大佬宁愿一些项目亏钱也 ...

  4. iOS KVO的原理

    KVO(Key Value Observing),是观察者模式在Foundation中的实现.   KVO的原理   简而言之就是:   1.当一个object有观察者时,动态创建这个object的类 ...

  5. C++:静态成员

    3.7.1 静态数据成员对象是类的一个实例,每个对象都具有自己的数据成员.例如,学生类张三或李四都具有自己的学号,姓名和平均成绩.在实际使用时,常常还需要一些其他的数据项,比如学生人数.总成绩.平均成 ...

  6. Java API —— 反射

    1.类加载器     1)类的加载         · 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化.         · 加载 :就是 ...

  7. C#版二维码生成器

    前言 本文所使用的二维码生成代码是谷歌开源的条形码图像处理库完成的,c#版的代码可去 这里   --  下载压缩包. 截止目前为止最新版本为2.2,提供以下编码格式的支持: UPC-A and UPC ...

  8. Xcode学习

    http://www.cnblogs.com/ygm900/p/3488881.html

  9. sdut 1728 编辑距离问题( dp )

    题目 思路:edit(i, j),它表示第一个字符串的长度为i的子串到第二个字符串的长度为j的子串的编辑距离. 有如下动态规划公式: if i == 0 且 j == 0,edit(i, j) = 0 ...

  10. bzoj1601: [Usaco2008 Oct]灌水

    经典延伸最小生成树问题... #include<cstdio> #include<cstring> #include<cctype> #include<alg ...