BZOJ 3218(a + b Problem-二分图套值域线段树)
出这题的人是怎么想出来的……
言归正传,这题是二分图套值域线段树。
首先经过 @Vfleaking的神奇建图后,把图拆成二分图,
不妨利用有向图最小割的性质建图(以前我一直以为最小割和边的方向无关,可这样的话很奇怪哦……)
理解悲剧……
我们可以利用边有向的性质解决黑白色块……
然后发现线段树很多……主席树闪亮登场
然后·就这麽A了?…………
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#include<cmath>
#include<cctype>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define RepD(i,n) for(int i=n;i>=0;i--)
#define MEM(a) memset(a,0,sizeof(a))
#define MEMI(a) memset(a,127,sizeof(a))
#define MEMi(a) memset(a,128,sizeof(a))
#define INF (2139062143)
#define MAXN (500000 +10)
#define MAXM (500000 +10)
int n,m,s,t;
int edge[MAXM],next[MAXM]={0},pre[MAXN]={0},weight[MAXM],size=1;
void addedge(int u,int v,int w)
{
edge[++size]=v;
weight[size]=w;
next[size]=pre[u];
pre[u]=size;
}
void addedge2(int u,int v,int w){/*cout<<u<<' '<<v<<' '<<w<<endl;*/addedge(u,v,w),addedge(v,u,0);}
int cnt[MAXN]={0},d[MAXN]={0};
long long totflow=0;
long long sap(int x,int flow)
{
if (x==t) return flow;
int nowflow=0;
Forp(x)
{
int &v=edge[p];
if (d[v]==d[x]-1&&weight[p])
{
long long fl=sap(v,min(weight[p],flow));
weight[p]-=fl,weight[p^1]+=fl,nowflow+=fl,flow-=fl;
if (!flow) return nowflow;
}
}
if (!(--cnt[d[x]++])) d[s]=t+1;
cnt[d[x]]++;
return nowflow;
}
struct node
{
node *ch[2];
node(){ch[0]=ch[1]=NULL;}
}q[MAXN],*root[MAXN]={NULL};
int tail=0;
void ins(node *&p,node *x,int l,int r,int c)
{
int m=(l+r) >>1;
p=&q[++tail];
if (x) *p=*x;
if (l==r) return;
if (c<=m) ins(p->ch[0],p->ch[0],l,m,c);
else ins(p->ch[1],p->ch[1],m+1,r,c);
}
void print(node *p)
{
//cout<<
}
node *ans[MAXN];
int ans_siz=0;
void qur(node *p,int l,int r,int L,int R)
{
if (!p||L>R) return;
int m=l+r >>1;
if (L<=l&&r<=R) {ans[++ans_siz]=p;return;}
if (l==r) return;
if (L<=m) qur(p->ch[0],l,m,L,R);
if (m<R) qur(p->ch[1],m+1,r,L,R);
}
int a2[MAXN],a[MAXN],b[MAXN],w[MAXN],l[MAXN],r[MAXN],p[MAXN];
int main()
{
freopen("bzoj3218.in","r",stdin);
// freopen(".out","w",stdout);
scanf("%d",&n);
For(i,n) scanf("%d%d%d%d%d%d",&a[i],&b[i],&w[i],&l[i],&r[i],&p[i]);
memcpy(a2,a,sizeof(a));
sort(a2+1,a2+n+1);
int size=unique(a2+1,a2+n+1)-(a2+1);
For(i,n)
{
a[i]=lower_bound(a2+1,a2+size+1,a[i])-(a2);
l[i]=lower_bound(a2+1,a2+size+1,l[i])-(a2);
r[i]=upper_bound(a2+1,a2+size+1,r[i])-(a2)-1;
}
For(i,n) ins(root[i],root[i-1],1,size,a[i]); s=2*n+1; t=2*n+2;
For(i,n) addedge2(s,i,b[i]),addedge2(i,t,w[i]),addedge2(i,n+i,p[i]);
For(i,tail)
{
if (q[i].ch[0]) addedge2(t+i,t+((q[i].ch[0])-q),INF);
if (q[i].ch[1]) addedge2(t+i,t+((q[i].ch[1])-q),INF);
}
For(i,n)
{
ans_siz=0;
qur(root[i],1,size,a[i],a[i]);
qur(root[i-1],1,size,a[i],a[i]);
node *cur=ans[1],*last=NULL;
if (ans_siz>1) last=ans[2];
//cout<<t+((cur)-(q))<<'*';
addedge2(t+((cur)-(q)),i,INF); if (ans_siz>1) addedge2(t+(cur-(q)),t+((last)-(q)),INF);
}
For(i,n)
{
ans_siz=0;
qur(root[i],1,size,l[i],r[i]);
For(j,ans_siz) addedge2(n+i,t+((ans[j])-(q)),INF);
}
//cout<<2*n+2+tail<<endl;
cnt[0]=2*n+2+tail;
while (d[s]<=t) {totflow+=sap(s,INF);}
//For(i,2*n+tail) cout<<d[i]<<' ';
long long ans=-totflow;
For(i,n) ans+=b[i]+w[i];
cout/*<<totflow<<' '*/<<ans<<endl; return 0;
}
BZOJ 3218(a + b Problem-二分图套值域线段树)的更多相关文章
- [BZOJ 3218] A + B Problem 【可持久化线段树 + 网络流】
题目连接:BZOJ - 3218 题目分析 题目要求将 n 个点染成黑色或白色,那么我们可以转化为一个最小割模型. 我们规定一个点 i 最后属于 S 集表示染成黑色,属于 T 集表示染成白色,那么对于 ...
- bzoj 3218 a + b Problem(最小割+主席树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3218 [题意] 给n个格子涂白或黑色,白则wi,黑则bi的好看度,若黑格i存在: 1& ...
- 【BZOJ】3339: Rmq Problem & 3585: mex(线段树+特殊的技巧)
http://www.lydsy.com/JudgeOnline/problem.php?id=3585 好神的题. 但是!!!!!!!!!!!!!!我线段树现在要开8倍空间才能过!!!!!!!!!! ...
- [BZOJ3065]带插入区间K小值 解题报告 替罪羊树+值域线段树
刚了一天的题终于切掉了,数据结构题的代码真**难调,这是我做过的第一道树套树题,做完后感觉对树套树都有阴影了......下面写一下做题记录. Portal Gun:[BZOJ3065]带插入区间k小值 ...
- BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)
题目大意:有一些位置.这些位置上能够放若干个数字. 如今有两种操作. 1.在区间l到r上加入一个数字x 2.求出l到r上的第k大的数字是什么 思路:这样的题一看就是树套树,关键是怎么套,怎么写.(话说 ...
- 值域线段树 bzoj 4627
这是题目链接4627: [BeiJing2016]回转寿司 题目大意: 给定n个数,求有多少个字段和在 满足 L<=sum<=R; 解题思路 需要解这个题目,需要有线段树加可持续化的思想, ...
- BZOJ.3307.雨天的尾巴(dsu on tree/线段树合并)
BZOJ 洛谷 \(dsu\ on\ tree\).(线段树合并的做法也挺显然不写了) 如果没写过\(dsu\)可以看这里. 对修改操作做一下差分放到对应点上,就成了求每个点子树内出现次数最多的颜色, ...
- POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询)
POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询) 题意分析 注意一下懒惰标记,数据部分和更新时的数字都要是long long ,别的没什么大 ...
- POJ 3468 A Simple Problem with Integers 【线段树】
题目链接 http://poj.org/problem?id=3468 思路 线段树 区间更新 模板题 在赋初始值的时候,按点更新区间就可以 AC代码 #include <cstdio> ...
随机推荐
- Codeforces Round #189 (Div. 2)
题目地址:http://codeforces.com/contest/320 第一题:基本题,判断mod 1000,mod 100.,mod 10是不是等于144.14.1,直到为0 代码如下: #i ...
- 凤凰OS
看看这个http://www.phoenixos.com 是不是你想要的 --- 共有 5 条评论 --- Entity回复 @Leaybc : 今天装的凤凰os,有很多的BUG整天还不错. ...
- WCF技术剖析之十:调用WCF服务的客户端应该如何进行异常处理
原文:WCF技术剖析之十:调用WCF服务的客户端应该如何进行异常处理 在前面一片文章(服务代理不能得到及时关闭会有什么后果?)中,我们谈到及时关闭服务代理(Service Proxy)在一个高并发环境 ...
- Hbiernate关联排序问题
使用场景: 假设有两张表请求信息.账户表,它们之间是一对多的关系.对应的java类分别为Sfcx_RequestInfo和Sfcx_Zhxx.Sfcx_RequestInfo有一个Set属性 sfcx ...
- premake在Ubuntu和GCC环境下创建简单的C++工程
由于premake基于lua脚本,为了方便编辑lua脚本,我在emacs24中利用package system安装了lua-mode. 然后创建config.lua文件,填入下面这段,主要来自:htt ...
- Oracle基础知识笔记(10) 约束
表尽管建立完毕了,可是表中的数据是否合法并不能有所检查,而假设要想针对于表中的数据做一些过滤的话,则能够通过约束完毕,约束的主要功能是保证表中的数据合法性,依照约束的分类,一共同拥有五种约束:非空约束 ...
- 初入Android--环境搭建
Android SDK 可以下载adt-bundle:包含了装好插件的eclipse和android sdk.下载好后,首先设置ANDROID_HOME环境变量:ANDROID_HOME=/home/ ...
- 图解C#_事件
概述 今天用来演示事件的例子是模拟实现一个文件下载类,在这个类中我将定义一个DownLoad事件,这个事件用来在文件下载的过程中,向订阅这个事件的用户发出消息,而这个消息将用DownLoadEvent ...
- 重操JS旧业第三弹:Array
数组在任何编程语言中都是非常重要的,因为函数在最大程度上代表了要实现的功能,而数组则是这些函数所要操作的内存一部分. 1 构建数组 js与其他非脚本语言的灵活之处在于要实现一个目标它可能具有多种方式, ...
- mysql存储过程及经常使用函数
一.函数 1.数学函数 CEIL()进一取整 SELECT CEIL(1.2);2 FLOOR()舍一取整 SELECT FLOOR(1.9);9 MOD取余数(取模) SELECT MOD(3,8) ...