3218: a + b Problem

Time Limit: 20 Sec  Memory Limit: 40 MB
Submit: 1320  Solved: 498
[Submit][Status][Discuss]

Description

Input

Output

Sample Input

Sample Output

HINT

Source

Solution

这道题非常吼啊!!

最小割的解法想一想还是比较容易想到的。

最大化价值的方法可以看成总和减去最小化损失。

暴力的解法就是$<S,i,b[i]>$割掉表示选白色,$<i',T,w[i]>$割掉表示选黑色,$<i,i',p[i]>$表示如果$i$和$i'$不同则付出代价,$<i',j,INF>$表示和$j$是不会被割的。

这样直接求出$mincut$,然后答案就是$\sum(b[i]+w[i])-mincut$。

但是这样的边数是$N^{2}$的,最后会被卡,所以要去优化。

这类情况的优化比较明显的就是影响的范围是一段区间,所以比较常见的是用线段树的节点去表示对一个区间的影响,来达到优化的目的,即连$<i',seg[l,r],INF>$。

首先肯定是线段树中的$<fa,son[0/1],INF>$,这里叶子节点直接连所对应的点,即$<leaf_{i},i,INF>$。

对于$1<=j<i$,可以考虑把普通的线段树换成可持久化线段树即可。

这里有一个问题就是$a[i]$用同一个叶子节点表示的会出现重复,所以需要新版本的叶子连向老版本的叶子$<new,old,INF>$

这样边数和点数都是$NlogN$的,就可以通过了。

搞起来有点蛋疼...思路清晰的话不是很难写。

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
inline int read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
} #define MAXN 100010
#define MAXM 750010 int N,a[MAXN],b[MAXN],w[MAXN],l[MAXN],r[MAXN],p[MAXN],ans;
struct EdgeNode{
int next,to,cap;
}edge[MAXM<<1];
int head[MAXN],cnt=1;
inline void AddEdge(int u,int v,int w) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v; edge[cnt].cap=w;}
inline void InsertEdge(int u,int v,int w) {/*printf("<%d %d>\n",u,v);*/ AddEdge(u,v,w); AddEdge(v,u,0);} #define INF 0x7fffffff
int h[MAXN],S,T,cur[MAXN];
inline bool bfs()
{
queue<int>q;
for (int i=S; i<=T; i++) h[i]=-1;
h[S]=1; q.push(S);
while (!q.empty())
{
int now=q.front(); q.pop();
for (int i=head[now]; i; i=edge[i].next)
if (h[edge[i].to]==-1 && edge[i].cap)
h[edge[i].to]=h[now]+1,q.push(edge[i].to);
}
return h[T]!=-1;
} inline int dfs(int loc,int low)
{
if (loc==T) return low;
int used=0,w;
for (int i=cur[loc]; i; i=edge[i].next)
if (edge[i].cap && h[edge[i].to]==h[loc]+1)
{
w=dfs(edge[i].to,min(edge[i].cap,low-used));
edge[i].cap-=w; edge[i^1].cap+=w; used+=w;
if (used==low) return low;
if (edge[i].to) cur[loc]=i;
}
if (!used) h[loc]=-1;
return used;
} int Dinic()
{
int tmp=0;
while (bfs())
{
for (int i=S; i<=T; i++) cur[i]=head[i];
tmp+=dfs(S,INF);
}
return tmp;
} namespace PrTree{
int sz,lson[MAXM],rson[MAXM],root[MAXN];
inline void Insert(int l,int r,int &x,int y,int pos,int id)
{
x=++sz;
if (l==r) {
InsertEdge(2*N+x,id,INF);
if (y) InsertEdge(2*N+x,2*N+y,INF);
return;
}
int mid=(l+r)>>1;
lson[x]=lson[y]; rson[x]=rson[y];
if (pos<=mid) Insert(l,mid,lson[x],lson[y],pos,id);
else Insert(mid+1,r,rson[x],rson[y],pos,id);
if (lson[x]) InsertEdge(2*N+x,2*N+lson[x],INF);
if (rson[x]) InsertEdge(2*N+x,2*N+rson[x],INF);
} inline void Query(int l,int r,int L,int R,int now,int id)
{
if (!now) return;
if (L<=l && R>=r) {
InsertEdge(id,2*N+now,INF);
return;
}
int mid=(l+r)>>1;
if (L<=mid) Query(l,mid,L,R,lson[now],id);
if (R>mid) Query(mid+1,r,L,R,rson[now],id);
} }using namespace PrTree; int ls[MAXN],tot;
int main()
{
N=read();
for (int i=1; i<=N; i++) a[i]=read(),b[i]=read(),w[i]=read(),l[i]=read(),r[i]=read(),p[i]=read(),ans+=w[i]+b[i];
for (int i=1; i<=N; i++) ls[++tot]=a[i],ls[++tot]=l[i],ls[++tot]=r[i]; sort(ls+1,ls+tot+1); tot=unique(ls+1,ls+tot+1)-ls-1; for (int i=1; i<=N; i++) a[i]=lower_bound(ls+1,ls+tot+1,a[i])-ls,l[i]=lower_bound(ls+1,ls+tot+1,l[i])-ls,r[i]=lower_bound(ls+1,ls+tot+1,r[i])-ls; S=0; for (int i=1; i<=N; i++) {
PrTree::Insert(1,tot,root[i],root[i-1],a[i],i);
PrTree::Query(1,tot,l[i],r[i],root[i-1],i+N);
} T=2*N+sz+1; for (int i=1; i<=N; i++) InsertEdge(S,i,b[i]),InsertEdge(i,T,w[i]),InsertEdge(i,i+N,p[i]); printf("%d\n",ans-Dinic());
return 0;
}

  

【BZOJ-3218】a+b Problem 最小割 + 可持久化线段树的更多相关文章

  1. 【BZOJ 3218】 3218: a + b Problem(最小割+可持久化线段树)

    3218: a + b Problem Time Limit: 20 Sec  Memory Limit: 40 MBSubmit: 1440  Solved: 545 Description Inp ...

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

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

  3. BZOJ 2588: Spoj 10628. Count on a tree-可持久化线段树+LCA(点权)(树上的操作) 无语(为什么我的LCA的板子不对)

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 9280  Solved: 2421 ...

  4. bzoj 4408: [Fjoi 2016]神秘数 数学 可持久化线段树 主席树

    https://www.lydsy.com/JudgeOnline/problem.php?id=4299 一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数.例如S={1,1,1 ...

  5. 【BZOJ 3524】【Poi2014】Couriers 可持久化线段树

    为什么这个主席树叫可持久化线段树,我不知道,具体得问达神.我无限T,然后DaD3zZ一针见血地指出了我的N*50爆内存导致无限编译超时O)ZO)ZO)Z真是太神啦.以图为鉴: 达神题解传送门:http ...

  6. BZOJ 3207: 花神的嘲讽计划Ⅰ( hash + 可持久化线段树 )

    O(NK)暴力搞出所有子串的哈希值, 然后就对哈希值离散化建权值线段树, 就是主席树的经典做法了.总时间复杂度O(NK+(N+Q)logN) ----------------------------- ...

  7. bzoj 3218 a + b Problem(最小割+主席树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3218 [题意] 给n个格子涂白或黑色,白则wi,黑则bi的好看度,若黑格i存在: 1& ...

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

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

  9. UOJ#77. A+B Problem [可持久化线段树优化建边 最小割]

    UOJ#77. A+B Problem 题意:自己看 接触过线段树优化建图后思路不难想,细节要处理好 乱建图无果后想到最小割 白色和黑色只能选一个,割掉一个就行了 之前选白色必须额外割掉一个p[i], ...

随机推荐

  1. JMS学习(五)--ActiveMQ中的消息的持久化和非持久化 以及 持久订阅者 和 非持久订阅者之间的区别与联系

    一,消息的持久化和非持久化 ①DeliveryMode 这是传输模式.ActiveMQ支持两种传输模式:持久传输和非持久传输(persistent and non-persistent deliver ...

  2. Android手机间无线互传功能探索及实现

    年前研究了一下Android如何实现无线互传的功能,写了个小demo,最近无事,遂整理一下,与各位共享.前期调研发现,Android想要实现无线互传有以下几种技术:1,Bluetooth通行已久,简单 ...

  3. 华中邀请赛现场赛F题 Seats

    题目链接:http://acm.whu.edu.cn/land/problem/detail?problem_id=1552 解题报告:题目意思应该很清楚,就是有n个人,分别属于7个班级,然后他们坐成 ...

  4. cordova app 监听物理返回键

    物理返回键指的是手机系统自带的返回按钮,通过cordova监听返回按钮操作,可以禁止某些页面的返回操作,以及实现点击两次返回按钮退出应用. var pageUrl = window.location. ...

  5. MPC&MAGIC

    MPC: Popularity-based Caching Strategy for Content Centric Networks MPC: most popular content MPC主要思 ...

  6. How to become a successful bug bounty hunter

    出处:https://www.hackerone.com/blog/become-a-successful-bug-bounty-hunter 如果你梦想成为赏金猎人,你的梦想就会成真 - 不要把你的 ...

  7. poj1679

    题意:给定一个无向连通图,问该图的最小生成树是否唯一. 分析:有一个定理,如果该图存在次小生成树(与原最小生成树不同,但长度小于等于原最小生成树),则一定可以通过从原最小生成树中去掉一个边并再入一个边 ...

  8. Python学习系列之(二)图解Windows8.1下安装Django

    一. 下载 去官网下载https://www.djangoproject.com/download/最新版,最新版本是1.6 二. 安装: 将下载下来的Django-1.6.tar.gz解压到D盘,接 ...

  9. 从零开始自己搭建复杂网络(以Tensorflow为例)

    从零开始自己搭建复杂网络(以MobileNetV2为例) tensorflow经过这几年的发展,已经成长为最大的神经网络框架.而mobileNetV2在经过Xception的实践与深度可分离卷积的应用 ...

  10. [转]Mahout推荐算法API详解

    Mahout推荐算法API详解 Hadoop家族系列文章,主要介绍Hadoop家族产品,常用的项目包括Hadoop, Hive, Pig, HBase, Sqoop, Mahout, Zookeepe ...