题意

http://uoj.ac/problem/77


思考

显然能转化为最小割模型。若没有pi的代价,则对于第i个格子,可以让源点连向第i个点,容量为黑色收益,再连向汇点,容量为白色收益。再考虑pi的代价,对1~n的每个点新建一个哨兵节点,并向它连容量为pi的边。若前面存在点j落在当前区间中,再将哨兵节点连向点j,容量为正无穷。

但这样边数达到O(n^2)级别,不能接受。

发现哨兵节点所连的边对于ai来说都是一个连续的区间,可用主席树优化建图,边数将为O(nlogn)级别。


代码

 #pragma GCC optimize 2
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll inf=INT_MAX;
int n;
int head[*+],size=;
int dfn[*],S,T;
int what[],tmp[],Last[];
ll valBoy[],valGirl[],a[],l[],r[],p[];
struct edge
{
int to,next;
ll w;
}E[*+];
inline ll max(ll x,ll y)
{
return x>y?x:y;
}
inline ll min(ll x,ll y)
{
return x<y?x:y;
}
inline void addEdge(int u,int v,ll w)
{
E[++size].to=v;
E[size].next=head[u];
E[size].w=w;
head[u]=size;
}
inline void add(int u,int v,ll w)
{
addEdge(u,v,w);
addEdge(v,u,);
}
bool bfs()
{
memset(dfn,-,sizeof(dfn));
queue<int>Q;
Q.push(S);
dfn[S]=;
while(!Q.empty())
{
int u=Q.front();
Q.pop();
for(int i=head[u];i;i=E[i].next)
{
int v=E[i].to;
if(dfn[v]!=-||E[i].w==)
continue;
dfn[v]=dfn[u]+;
Q.push(v);
}
}
return dfn[T]!=-;
}
ll dinic(int u,ll up)
{
if(u==T)
return up;
ll sum=;
for(int i=head[u];i;i=E[i].next)
{
int v=E[i].to;
if(dfn[v]!=dfn[u]+||E[i].w==)
continue;
ll g=dinic(v,min(E[i].w,up-sum));
E[i].w-=g;
E[i^].w+=g;
sum+=g;
if(g==)
dfn[v]=-;
if(sum==up)
break;
}
return sum;
}
struct czyTree
{
int t[*],cur,root[],son[*][];
int tot;
void addPos(int pos,int l,int r,int&num,int pre,int from)
{
num=++tot;
son[num][]=son[pre][],son[num][]=son[pre][];
if(l==r)
{
add(num+T,from,inf);
if(Last[pos])
add(num+T,Last[pos]+T,inf);
Last[pos]=num;
return;
}
int mid=(l+r)>>;
if(pos<=mid)
addPos(pos,l,mid,son[num][],son[pre][],from);
else
addPos(pos,mid+,r,son[num][],son[pre][],from);
if(son[num][])
add(num+T,son[num][]+T,inf);
if(son[num][])
add(num+T,son[num][]+T,inf);
}
void addS(int L,int R,int l,int r,int num,int from)
{
if(!num)
return;
if(L<=l&&r<=R)
{
add(from,num+T,inf);
return;
}
int mid=(l+r)>>;
if(R<=mid)
addS(L,R,l,mid,son[num][],from);
else if(mid<L)
addS(L,R,mid+,r,son[num][],from);
else
addS(L,R,l,mid,son[num][],from),addS(L,R,mid+,r,son[num][],from);
}
}Tree;
int main()
{
ios::sync_with_stdio(false);
cin>>n;
int tot=;
for(int i=;i<=n;++i)
{
cin>>a[i]>>valBoy[i]>>valGirl[i]>>l[i]>>r[i]>>p[i];
tmp[++tot]=a[i];
}
sort(tmp+,tmp+tot+);
// tot=unique(tmp+1,tmp+tot+1)-tmp-1;
S=,T=*n+;
for(int i=;i<=n;++i)
{
add(S,i,valBoy[i]);
add(i,T,valGirl[i]);
add(i,i+n,p[i]);
}
for(int i=;i<=n;++i)
{
int L=,R=tot;
while(tmp[L]<l[i]&&L<=tot)
++L;
while(r[i]<tmp[R]&&R)
--R;
Tree.addS(L,R,,tot,Tree.root[i-],i+n);
Tree.addPos(lower_bound(tmp+,tmp+tot+,a[i])-tmp,,tot,Tree.root[i],Tree.root[i-],i);
}
ll ans=;
while(bfs())
ans+=dinic(S,inf);
for(int i=;i<=n;++i)
ans-=valBoy[i]+valGirl[i];
cout<<-ans<<endl;
return ;
}

细节

如下图所示,若此题使用dinic,左右两个建图方式是不等价的,且左图是正确的,右图是错误的,并且右图的最小割结果会变小。(假设有很多蓝色边)

事实上,哨兵节点连出的边必须连在左边一排点上。

考虑下图所示情况。在dinic中,若先走了红色路径,则无法经过蓝色路径。原因是蓝色正无穷边此时不存在反向边,蓝色路径不连通。这样,最小割就少了一些流量。

此外,在主席树建图中,要注意相同ai的点要连向前一个相同ai的点。

(CORRECTED BY CZY)

[集训]dance的更多相关文章

  1. QDEZ集训笔记【更新中】

    这是一个绝妙的比喻,如果青岛二中的台阶上每级站一只平度一中的猫,差不多站满了吧 自己的理解 [2016-12-31] [主席树] http://www.cnblogs.com/candy99/p/61 ...

  2. BZOJ 1305: [CQOI2009]dance跳舞 二分+最大流

    1305: [CQOI2009]dance跳舞 Description 一次舞会有n个男孩和n个女孩.每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞.每个男孩都不会和同一个女孩跳两首(或更多)舞曲 ...

  3. Malek Dance Club(递推)

    Malek Dance Club time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  4. iOS开发笔记15:地图坐标转换那些事、block引用循环/weak–strong dance、UICollectionviewLayout及瀑布流、图层混合

    1.地图坐标转换那些事 (1)投影坐标系与地理坐标系 地理坐标系使用三维球面来定义地球上的位置,单位即经纬度.但经纬度无法精确测量距离戒面积,也难以在平面地图戒计算机屏幕上显示数据.通过投影的方式可以 ...

  5. BZOJ-1305 dance跳舞 建图+最大流+二分判定

    跟随YveH的脚步又做了道网络流...%%% 1305: [CQOI2009]dance跳舞 Time Limit: 5 Sec Memory Limit: 162 MB Submit: 2119 S ...

  6. UVA 1291 十四 Dance Dance Revolution

    Dance Dance Revolution Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Su ...

  7. UVALive 4222 Dance 模拟题

    Dance 题目连接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&pag ...

  8. 2015UESTC 暑假集训总结

    day1: 考微观经济学去了…… day2: 一开始就看了看一道题目最短的B题,拍了半小时交了上去wa了 感觉自己一定是自己想错了,于是去拍大家都过的A题,十分钟拍完交上去就A了 然后B题写了一发暴力 ...

  9. JS省队集训记

    不知不觉省队集训已经结束,离noi也越来越近了呢 论考前实战训练的重要性,让我随便总结一下这几天的考试 Day 1 T1 唉,感觉跟xj测试很像啊?meet in middle,不过这种题不多测是什么 ...

随机推荐

  1. 学习Java第二周

    这是学习java的第二周,又这样不知不觉的结束了 上周想要学习的这一周也都做到了,可是觉得进度有些慢了,学习了: 1. 接口和抽象类: 2. 集合与数组: 3. 方法的定义: 4. 递归算法: 5.对 ...

  2. Elasticsearch慢查询故障诊断

    最近在做ES搜索调优,看了一些lucene搜索的文档和代码,本文用于总结调优过程中学到的知识和自己的思考. 在抓到ES慢查询之后,会通过profile或者kibana的Search Profiler ...

  3. Python_全局变量的定义

    1.在my套件下新建一个关键字systemkey并进行脚本的编写:创建一个${var1}变量,并赋值为aaaaaaaaaa Set Global Variable        ${var1}    ...

  4. .NETCore3.1中的Json互操作最全解读-收藏级

    前言 本文比较长,我建议大家先点赞.收藏后慢慢阅读,点赞再看,形成习惯! 我很高兴,.NETCore终于来到了3.1LTS版本,并且将支持3年,我们也准备让部分业务迁移到3.1上面,不过很快我们就遇到 ...

  5. 如何选择API测试工具

    没有最好,只有最合适. 如今,越来越多的公司正在向DevOps的方向左转,以实现持续集成和持续部署开发.这意味着我们的反馈需要比以往更快,以便确定我们的应用程序是否准备好交付.这就是API测试如此重要 ...

  6. Oracle:存储过程的使用

    Oracle:存储过程的使用 以sys身份登录,创建用户c##zs,密码111,分配dba角色 以c##zs身份登录,导入数据表 编写存储过程,根据学生学号,查询出学生所选课程成绩等级, 打印结果示例 ...

  7. Head First设计模式——组合模式

    最近比较忙,有段时间没有更新设计模式的进度了.今天继续学习组合设计模式. 组合模式的例子我们继续延续上篇<Head First设计模式——迭代器模式>的菜单例子,首先声明下迭代器和组合模式 ...

  8. 「Luogu P3183」[HAOI2016]食物链 解题报告

    身为一个蒟蒻,由于刷不过[NOI2001]食物链 于是出门左转写了道另一道假的食物链 戳这里 这里的食物链个条数其实就是有向图的路径数(应该是这么说吧,我弱) 思路: 拓扑(Topulogy)(一本正 ...

  9. Educational Codeforces Round 53 (Rated for Div. 2) (前五题题解)

    这场比赛没有打,后来补了一下,第五题数位dp好不容易才搞出来(我太菜啊). 比赛传送门:http://codeforces.com/contest/1073 A. Diverse Substring ...

  10. 手把手带你了解消息中间件(3)——RocketMQ

    一.RocketMQ简介   RocketMQ作为一款纯java.分布式.队列模型的开源消息中间件,支持事务消息.顺序消息.批量消息.定时消息.消息回溯等. 二.RocketMQ架构   如图所示为R ...