题面

传送门

思路

最小割

我们首先忽略掉那个奇♂怪的限制,就有一个比较显然的最小割模型:

建立源点$S$和汇点$T$

对于每个元素$i$建立一个点$i$,连边$<S,i,w[i]>$和$<i,T,b[i]>$

这样,割掉$<S,i>$边就表示选白色,割掉$<i,T>$边就表示选黑色,那么答案就是$\sum_{i=1}^nb[i]+w[i] - mincut$

但是现在有一个奇♂怪的限制出来了

奇♂怪的限制

这个限制,是当$i$点黑色,$j<i$点白色时出现的

那么我们考虑把这个限制对答案的影响,也用最小割的方式表现出来

我们发现,如果对于某一个点$i$,它对应的割边(就是在上面那种方法里面)是$<i,T>$,也就是它取白色的话,这个限制不会被触发

那么我们就考虑这个点的割边是$<S,i>$的情况,此时我们发现,如果我们想把这个$p[i]$也变成最小割的一部分的话,我们就要对于所有可能触发的$j$,构成一条这样的链:

$<S,i>-<i,j>-<j,T>$

但是这个中间这条,显然不能直接在$i,j$中间连边,因为这样无法体现出链的特性

我们考虑这样的一个方法,来分开黑白割的情况

我们对于每个点,新建节点$ii$,然后对于每个$ii$,连边$<ii,i,p[i]>$

对于$i$所有能够访问到的点,连边$<i,jj,inf>$,$inf$表示不可割

这样跑最小割,还是用所有的$b,w$的和来减,就是答案了

建图优化

显然这个东西直接连边的话,$n^2$的会炸

所以我们用一个主席树来优化一下建图

用所有的$i$连向对应的主席树链上的所有点,主席树上的点就横向连边(旧的往新的连),然后每个点从它覆盖的所有区间连过来

开的主席树的数组下标意义就是$a$的大小,这样方便取区间

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<cassert>
  6. #include<cmath>
  7. #define ll long long
  8. using namespace std;
  9. inline int read(){
  10. int re=0,flag=1;char ch=getchar();
  11. while(ch>'9'||ch<'0'){
  12. if(ch=='-') flag=-1;
  13. ch=getchar();
  14. }
  15. while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
  16. return re*flag;
  17. }
  18. int n,first[200010],cnte=-1,dep[200010],cur[200010];
  19. struct edge{
  20. int to,next;ll w;
  21. }a[1500010];
  22. void add(int u,int v,ll w){
  23. a[++cnte]=(edge){v,first[u],w};first[u]=cnte;
  24. a[++cnte]=(edge){u,first[v],0};first[v]=cnte;
  25. }
  26. bool bfs(int s,int t){
  27. int i,u,v,q[200010],head=0,tail=1;
  28. for(i=s;i<=t;i++) dep[i]=-1,cur[i]=first[i];
  29. dep[s]=0;q[0]=s;
  30. while(head<tail){
  31. u=q[head++];
  32. for(i=first[u];~i;i=a[i].next){
  33. v=a[i].to;if(~dep[v]||!a[i].w) continue;
  34. dep[v]=dep[u]+1;q[tail++]=v;
  35. }
  36. }
  37. return ~dep[t];
  38. }
  39. int dfs(int u,int t,ll lim){
  40. if(u==t||!lim) return lim;
  41. int i,v,f,flow=0;
  42. for(i=cur[u];~i;i=a[i].next){
  43. v=a[i].to;cur[u]=i;
  44. if(dep[v]==dep[u]+1&&(f=dfs(v,t,min(a[i].w,lim)))){
  45. flow+=f;lim-=f;
  46. a[i].w-=f;a[i^1].w+=f;
  47. if(!lim) return flow;
  48. }
  49. }
  50. if(lim) dep[u]=-1;
  51. return flow;
  52. }
  53. ll dinic(int s,int t){
  54. ll re=0;
  55. while(bfs(s,t)) re+=dfs(s,t,1e12);
  56. return re;
  57. }
  58. struct chairmantree{
  59. int ch[1000010][2],cnt,root[5010];
  60. int insert(int l,int r,int pos,int pre,int u){
  61. int cur=++cnt;
  62. ch[cur][0]=ch[pre][0];ch[cur][1]=ch[pre][1];
  63. add(u,cur,1e12);
  64. if(l==r){
  65. if(pre) add(pre,cur,1e12);
  66. return cur;
  67. }
  68. int mid=(l+r)>>1;
  69. if(mid>=pos){
  70. ch[cur][0]=insert(l,mid,pos,ch[pre][0],u);
  71. if(pre) add(pre,cur,1e12);
  72. }
  73. else{
  74. ch[cur][1]=insert(mid+1,r,pos,ch[pre][1],u);
  75. if(pre) add(pre,cur,1e12);
  76. }
  77. return cur;
  78. }
  79. void check(int l,int r,int ql,int qr,int cur,int u){
  80. if(!cur) return;
  81. int mid=(l+r)>>1;
  82. if(l>=ql&&r<=qr){
  83. add(cur,u,1e12);
  84. return;
  85. }
  86. if(mid>=ql) check(l,mid,ql,qr,ch[cur][0],u);
  87. if(mid<qr) check(mid+1,r,ql,qr,ch[cur][1],u);
  88. }
  89. }T;
  90. int main(){
  91. memset(first,-1,sizeof(first));
  92. n=read();int i,val,b,w,l,r,p;ll sum=0;
  93. int s=0,t=200000;T.cnt=n<<1;
  94. for(i=1;i<=n;i++){
  95. val=read();b=read();w=read();l=read();r=read();p=read();
  96. sum+=(ll)b+w;
  97. add(s,i,w);add(i,t,b);add(i+n,i,p);
  98. T.root[i]=T.insert(0,1e9,val,T.root[i-1],i);
  99. T.check(0,1e9,l,r,T.root[i-1],i+n);
  100. }
  101. printf("%lld\n",sum-dinic(s,t));
  102. }

[bzoj3218] a+b problem [最小割+数据结构优化建图]的更多相关文章

  1. cf786E ALT (最小割+倍增优化建图)

    如果把“我全都要”看作是我全不要的话,就可以用最小割解决啦 源点S,汇点T 我们试图让每个市民作为一个等待被割断的路径 把狗狗给市民:建边(S,i,1),其中i是市民 把狗狗给守卫:建边(j,T,1) ...

  2. [bzoj3218]a + b Problem 网络流+主席树优化建图

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

  3. bzoj5017 [Snoi2017]炸弹 (线段树优化建图+)tarjan 缩点+拓扑排序

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5017 题解 这个题目方法挺多的. 线段树优化建图 线段树优化建图的做法应该挺显然的,一个炸弹能 ...

  4. 一个神秘的oj2587 你猜是不是dp(线段树优化建图)

    哇 这难道不是happiness的翻版题嘛? 从\(S\)向一个点连染成白色的收益 从这个点向\(T\)连染成黑色的收益 对于额外的收益,建一个辅助点,跟区间内的每个点连\(inf\),然后向S/T, ...

  5. [SDOI2017]天才黑客[最短路、前缀优化建图]

    题意 一个 \(n\) 点 \(m\) 边的有向图,还有一棵 \(k\) 个节点的 trie ,每条边上有一个字符串,可以用 trie 的根到某个节点的路径来表示.每经过一条边,当前携带的字符串就会变 ...

  6. CF1007D. Ants(树链剖分+线段树+2-SAT及前缀优化建图)

    题目链接 https://codeforces.com/problemset/problem/1007/D 题解 其实这道题本身还是挺简单的,这里只是记录一下 2-SAT 的前缀优化建图的相关内容. ...

  7. poj3680 Intervals 区间k覆盖问题 最小费用最大流 建图巧妙

    /** 题目:poj3680 Intervals 区间k覆盖问题 最小费用最大流 建图巧妙 链接:http://poj.org/problem?id=3680 题意:给定n个区间,每个区间(ai,bi ...

  8. 【bzoj3073】[Pa2011]Journeys 线段树优化建图+堆优化Dijkstra

    题目描述 Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N编号,但是他发现道路实在太多了,他要一条条建简直是不可能的!于是他以如下方式建造道路:(a, ...

  9. BZOJ_4276_[ONTAK2015]Bajtman i Okrągły Robin_线段树优化建图+最大费用最大流

    BZOJ_4276_[ONTAK2015]Bajtman i Okrągły Robin_线段树优化建图+最大费用最大流 Description 有n个强盗,其中第i个强盗会在[a[i],a[i]+1 ...

随机推荐

  1. SSI框架下,用jxl实现导出功能

    SSI框架下,用jxl实现导出功能 先说明一下,这个是SSI框架下,前端用ExtJs,应用在一个企业级的系统中的导出功能,因为是摸索着做的,所以里面有一些代码想整理一下,如果有人看到了,请视自己的架构 ...

  2. OCCI线程安全

    线程是任务调度的基本单位,一个进程中可以有多个线程,每个线程有自己的堆栈空间, 进程中的代码段.数据段和堆栈对进程中的线程是可见的.在使用线程时通常都要考虑数据的安全访问. 常用的线程同步方法有: 互 ...

  3. 1237: [SCOI2008]配对

    Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1789  Solved: 715[Submit][Status][Discuss] Descripti ...

  4. python基础数据类型之字典的操作

    一. 字典的简单介绍字典(dict)是python中唯一的一个映射类型.他是以{ }括起来的键值对组成. 在dict中key是唯一的. 在保存的时候, 根据key来计算出一个内存地址. 然后将key- ...

  5. 浅谈MySQL字符集

      Preface       MySQL use character set & collation to organize the different charater.It provid ...

  6. 统计寄存器AX中1 的个数

    ;==================================== ; 统计寄存器AX中1 的个数 DATAS segment DATAS ends CODES segment START: ...

  7. python__高级 : Property 的使用

    一个类中,假如一个私有属性,有两个方法,一个是getNum , 一个是setNum 它,那么可以用 Property 来使这两个方法结合一下,比如这样用  num = property(getNum, ...

  8. 【JavaScript】jQuery绑定事件

    jquery中直接绑定事件:只能用在程序中一开始就存在的html代码 目标元素.click(function(){ }) jquery中间接绑定事件: 如果目标元素是js生成的,则需要间接绑定事件,用 ...

  9. OLAP和OLTP

    OLTP与OLAP的介绍 数据处理分为两种技术架构系统:OLTP与OLAP OLTP(联机事务处理过程) OLTP是传统的关系型数据库的主要应用,主要是基本的,日常的事务处理,例如银行的交易     ...

  10. python_字符串_常用处理

    1. 输出原序列的反向互补序列 in1 = open("brca1.fasta", "r") out1 = open("re_brca1.fasta& ...