Description

Input

Output

Sample Input

10
0 1 7 3 9 2
7 4 0 9 10 5
1 0 4 2 10 2
7 9 1 5 7 2
6 3 5 3 6 2
6 6 4 1 8 1
6 1 6 0 6 5
2 2 5 0 9 3
5 1 3 0 2 5
5 6 7 1 1 2

Sample Output

55
题解:
这题要好好总结,真是抓狂的A+B problem.
首先非常容易想到O(n^2)空间复杂度的网络流建图,和为了博多一题类似(SUM-不合法),区别在于中间那条双向边改成单向边.
因为一个点只有一次被认为是奇怪方格的机会,所以拆点(i',i,p[i]),限制p[i],所以枚举前i个点,满足条件就连边到i'
综上:
连(S,i,w[i])(i,T,b[i])(i',i,p[i]) 如果满足条件的j (j,i',inf)
这样空间显然不允许,然后就来了奇怪的主席树上跑网络流,直接建好树以后把(j,i',inf)改成j连主席树上的点即可
被i覆盖的区间我们就在主席树上向j’连边 大致图如下 对所有点都做相同处理:
HINT:
1.傻逼错误:为了省内存num初值设为-1....然后for里没改.
2.很重要的地方:i连向的旧节点要对新节点建边,不然在主席树上无法流通

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 using namespace std;
 8 const int N=12333,M=3200005,inf=2e9;
 9 typedef long long ll;
10 int head[N],num=-1;
11 struct Lin{
12     int next,to,dis;
13 }a[M];
14 int gi(){
15     int str=0;char ch=getchar();
16     while(ch>'9' || ch<'0')ch=getchar();
17     while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
18     return str;
19 }
20 void init(int x,int y,int dis){
21     a[++num].next=head[x];a[num].to=y;a[num].dis=dis;head[x]=num;
22 }
23 void addedge(int x,int y,int dis){
24     init(x,y,dis);init(y,x,0);
25 }
26 int n,s[N],q[N],b[N],w[N],l[N],r[N],p[N],S=0,T,dep[N];
27 bool bfs(){
28     memset(dep,0,sizeof(dep));
29     int u,x,t=0,sum=1;
30     q[1]=S;dep[S]=1;
31     while(t!=sum){
32         x=q[++t];
33         for(int i=head[x];i;i=a[i].next){
34             u=a[i].to;
35             if(dep[u] || a[i].dis<=0)continue;
36             dep[u]=dep[x]+1;q[++sum]=u;
37         }
38     }
39     return dep[T];
40 }
41 int dfs(int x,int flow){
42     if(!flow || x==T)return flow;
43     int tmp,tot=0,u;
44     for(int i=head[x];i;i=a[i].next){
45         u=a[i].to;
46         if(dep[u]!=dep[x]+1 || a[i].dis<=0)continue;
47         tmp=dfs(u,min(flow,a[i].dis));
48         a[i].dis-=tmp;a[i^1].dis+=tmp;
49         tot+=tmp;flow-=tmp;
50         if(!flow)break;
51     }
52     if(!tot)dep[x]=0;
53     return tot;
54 }
55 int maxflow(){
56     int tot=0,tmp;
57     while(bfs()){
58         tmp=dfs(S,inf);
59         while(tmp)tot+=tmp,tmp=dfs(S,inf);
60     }
61     return tot;
62 }
63 void work(){
64     n=gi();T=2*n+1;ll ans=0;
65     for(int i=1;i<=n;i++){
66         s[i]=gi();b[i]=gi();w[i]=gi();l[i]=gi();r[i]=gi();p[i]=gi();
67         ans+=b[i]+w[i];
68     }
69     for(int i=1;i<=n;i++){
70         addedge(S,i,w[i]);addedge(i,T,b[i]);addedge(i+n,i,p[i]);
71         for(int j=1;j<i;j++){
72             if(l[i]<=s[j] && s[j]<=r[i])addedge(j,i+n,p[i]);
73         }
74     }
75     ans=ans-maxflow();
76     printf("%lld\n",ans);
77 }
78 int main()
79 {
80     freopen("pp.in","r",stdin);
81     work();
82     return 0;
83 }

朴素做法

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <cstdio>
  6 #include <cmath>
  7 using namespace std;
  8 const int N=303333,M=820005,inf=2e9;
  9 typedef long long ll;
 10 int head[N],num=1,cnt=0,lim=0;
 11 struct Lin{
 12     int next,to,dis;
 13 }a[M];
 14 int gi(){
 15     int str=0;char ch=getchar();
 16     while(ch>'9' || ch<'0')ch=getchar();
 17     while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
 18     return str;
 19 }
 20 void init(int x,int y,int dis){
 21     a[++num].next=head[x];a[num].to=y;a[num].dis=dis;head[x]=num;
 22 }
 23 void addedge(int x,int y,int dis){
 24     init(x,y,dis);init(y,x,0);
 25 }
 26 int n,s[N],q[N],b[N],w[N],L[N],R[N],p[N],S=0,T,dep[N];
 27 bool bfs(){
 28     memset(dep,0,sizeof(dep));
 29     int u,x,t=0,sum=1;
 30     q[1]=S;dep[S]=1;
 31     while(t!=sum){
 32         x=q[++t];
 33         for(int i=head[x];i;i=a[i].next){
 34             u=a[i].to;
 35             if(dep[u] || a[i].dis<=0)continue;
 36             dep[u]=dep[x]+1;q[++sum]=u;
 37         }
 38     }
 39     return dep[T];
 40 }
 41 int dfs(int x,int flow){
 42     if(!flow || x==T)return flow;
 43     int tmp,tot=0,u;
 44     for(int i=head[x];i;i=a[i].next){
 45         u=a[i].to;
 46         if(dep[u]!=dep[x]+1 || a[i].dis<=0)continue;
 47         tmp=dfs(u,min(flow,a[i].dis));
 48         a[i].dis-=tmp;a[i^1].dis+=tmp;
 49         tot+=tmp;flow-=tmp;
 50         if(!flow)break;
 51     }
 52     if(!tot)dep[x]=0;
 53     return tot;
 54 }
 55 int maxflow(){
 56     int tot=0,tmp;
 57     while(bfs()){
 58         tmp=dfs(S,inf);
 59         while(tmp)tot+=tmp,tmp=dfs(S,inf);
 60     }
 61     return tot;
 62 }
 63 struct Segtree{
 64     int ls,rs;
 65 }Tree[N<<1];
 66 int root[N];
 67 void updata(int &rt,int last,int l,int r,int ask,int id){
 68     rt=++cnt;Tree[rt]=Tree[last];
 69     if(l==r){
 70         addedge(id,rt+T,inf);
 71         if(last)addedge(last+T,rt+T,inf);
 72         return ;
 73     }
 74     int mid=(l+r)>>1;
 75     if(ask<=mid)updata(Tree[rt].ls,Tree[last].ls,l,mid,ask,id);
 76     else updata(Tree[rt].rs,Tree[last].rs,mid+1,r,ask,id);
 77     if(Tree[rt].ls)addedge(Tree[rt].ls+T,rt+T,inf);if(Tree[rt].rs)addedge(Tree[rt].rs+T,rt+T,inf);
 78 }
 79 void query(int rt,int l,int r,int sa,int se,int id){
 80     if(!rt)return ;
 81     if(sa<=l && r<=se){
 82         addedge(rt+T,id+n,inf);
 83         return ;
 84     }
 85     int mid=(l+r)>>1;
 86     if(sa<=mid)query(Tree[rt].ls,l,mid,sa,se,id);
 87     if(se>mid)query(Tree[rt].rs,mid+1,r,sa,se,id);
 88 }
 89 void build(){
 90     for(int i=1;i<=n;i++){
 91         addedge(S,i,w[i]);addedge(i+n,i,p[i]);addedge(i,T,b[i]);
 92         if(i>1)query(root[i-1],0,lim,L[i],R[i],i);
 93         updata(root[i],root[i-1],0,lim,s[i],i);
 94     }
 95 }
 96 void work(){
 97     n=gi();T=2*n+1;ll ans=0;
 98     for(int i=1;i<=n;i++){
 99         s[i]=gi();b[i]=gi();w[i]=gi();L[i]=gi();R[i]=gi();p[i]=gi();
100         if(R[i]>lim)lim=R[i];if(L[i]>lim)lim=L[i];if(s[i]>lim)lim=s[i];
101         ans+=b[i]+w[i];
102     }
103     build();
104     ans=ans-maxflow();
105     printf("%lld\n",ans);
106 }
107 int main()
108 {
109     //freopen("pp.in","r",stdin);
110     work();
111     return 0;
112 }

主席树维护的网络流

转载于:https://www.cnblogs.com/Yuzao/p/7219922.html

bzoj 3218: a + b Problem相关推荐

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

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

  2. BZOJ 3218 UOJ #77 A+B Problem (主席树、最小割)

    BZOJ 3218 UOJ #77 A+B Problem (主席树.最小割) 大名鼎鼎的A+B Problem, 主席树优化最小割-- 调题死活调不对,一怒之下改了一种写法交上去A了,但是改写法之后 ...

  3. 【BZOJ】3339: Rmq Problem 3585: mex(线段树+特殊的技巧)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3585 好神的题. 但是!!!!!!!!!!!!!!我线段树现在要开8倍空间才能过!!!!!!!!!! ...

  4. BZOJ 4679/Hdu5331 Simple Problem LCT or 树链剖分

    4679: Hdu5331 Simple Problem 题意: 考场上,看到这道题就让我想起BZOJ4712洪水.然后思路就被带着飞起了,完全没去考虑一条链的情况,于是GG. 解法:先考虑一条链的做 ...

  5. BZOJ 3218(a + b Problem-二分图套值域线段树)

    出这题的人是怎么想出来的-- 言归正传,这题是二分图套值域线段树. 首先经过 @Vfleaking的神奇建图后,把图拆成二分图, 不妨利用有向图最小割的性质建图(以前我一直以为最小割和边的方向无关,可 ...

  6. 【BZOJ 2301】[HAOI2011]Problem b

    Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. Input 第一行一个整数 ...

  7. 【bzoj 3339】Rmq Problem 【bzoj 3585】mex(可持久化线段树)

    传送门biu~biu~ 两道题区别只在于ai的范围,显然>=n的那些ai都是没有意义的,因此两题相同. 权值线段树上的i点记录数字i的最右出现位置,查询区间[l,r]即为查询第r棵线段树上最小的 ...

  8. [NetworkFlow]网络流建模相关

    流 网络流问题本质上是线性规划问题的应用之一,线性规划问题的标准形式是给出一组等式约束和不等式约束,要求最优化一个线性函数. 在流问题中,变量以流量的形式出现在问题中,我们给出一个流网络(以有向图的形 ...

  9. BZOJ 2157 「国家集训队」旅游(树链剖分,线段树,边权转点权)【BZOJ计划】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2157 是 hydro 的 BZOJ ...

最新文章

  1. BZOJ 4422 Cow Confinement (线段树、DP、扫描线、差分)
  2. 微信公众平台 图片 java_Java微信公众平台之素材管理
  3. mac远程怎么操作?苹果电脑怎么远程协助?
  4. 999元/1499元起!Redmi Note 10系列正式首销
  5. python变量类型字符串的内建函数使用
  6. celery 停止_celery 停止执行中 task
  7. zz backgroundworker C#
  8. c#转换XML文件和json对象
  9. 向架构师进军---系统架构设计基础知识
  10. 阿里弹性云手机正式公测
  11. 基于NLTK的命名实体识别(分词、词性标注) 及windows系统64位—在python3下安装nltk
  12. 工具分享-Windows 的绿色软件工具集
  13. Unity在Hex与Color之间的颜色转换
  14. [集训队作业2018]uoj 449 喂鸽子 - min-max容斥 - dp - NTT
  15. 拆弹专家【爆改车间主任】学习笔记(2)小结
  16. 判断windows系统类型和IE浏览器版本
  17. Python语言在人工智能(AI)中的优势
  18. android手机 一键还原,安卓手机一键恢复通讯录
  19. 【计算几何】向量叉积和凸包 | 引射线法 | 判断点是否在多边形内部 | 葛立恒扫描法 | Cross Product and Convex Hul
  20. OpenSSL自建CA和签发二级CA及颁发SSL证书

热门文章

  1. Mysql(7)——auto_increment简介
  2. java通过对.class文件字节码加密,不被轻易反编译出源代码,分析及其实现。
  3. 说说FATFS文件系统(转)
  4. 静态、动态内存分配比较
  5. 2264: sequence(KMP)
  6. C++之vector容器初学(二)——插入和删除
  7. Nested `constexpr` function calls before definition in a constant-expression context
  8. IDEA配置git环境
  9. 图的基本运算及智能交通中的最佳路径选择问题
  10. 芦溪中学2021高考成绩查询,三台县芦溪中学2021年招生简章