BZOJ1178 [Apio2009]CONVENTION会议中心 贪心 set
欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - BZOJ1178
题意概括
一堆线段,现在取出最多条数,使其互不覆盖,并输出字典序最小的方案。
题解
这题好坑。
首先,注意一点,最后不能有多余的空格。
第一问就是基础的线段覆盖。
关键在于第二问。
我们要准备一个函数—— Get_Ans(L,R),用来求解L~R这个区间内,最多可以取多少线段。
这个可以O(log n)解决。前提是倍增预处理。
然后就是关键部分。
我们按照字典序从小到大,能选择就选择。
怎么判断是否可以选择?只需要在之前选择的线段空隙中可以放这个线段,并且满足Get_Ans(这个线段到它左边的第一条线段之前)+Get_Ans(它到它右边的第一个线段之前)+1 = Get_Ans(他左右两端的),那么就可以放进去。
代码
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <set>
using namespace std;
const int N=200000+5,Inf=1e9;
struct seg{
int L,R;
bool operator < (const seg x) const {
if (L==x.L)
return R>x.R;
return L<x.L;
}
}s[N],s2[N];
int n,rn,Hash[N*2],hs,p[N][20],L[N];
bool alive[N],vis[N*2];
set <int> S;
void HASH(){
sort(Hash+1,Hash+hs+1);
int hs_=1;
for (int i=2;i<=hs;i++)
if (Hash[i]!=Hash[i-1])
Hash[++hs_]=Hash[i];
hs=hs_;
}
void Delete(){
for (int i=1;i<=n;i++)
s2[i]=s[i];
sort(s+1,s+n+1);
memset(alive,true,sizeof alive);
int MinR=Inf,n_=0;
for (int i=n;i>=1;i--)
if (MinR>s[i].R)
MinR=s[i].R;
else
alive[i]=0;
for (int i=1;i<=n;i++)
if (alive[i])
s[++n_]=s[i];
n=n_;
}
void Get_Pos(){
memset(p,0,sizeof p);
for (int i=1;i<=n;i++)
L[i]=s[i].L;
L[n+1]=Inf;
for (int i=1;i<=n;i++){
p[i][0]=upper_bound(L+1,L+n+2,s[i].R)-L;
if (p[i][0]==n+1)
p[i][0]=0;
}
for (int i=1;i<=18;i++)
for (int j=1;j<=n;j++)
p[j][i]=p[p[j][i-1]][i-1];
}
int Get_Ans(int Le,int Ri){
if (Le>Ri||Le>hs)
return 0;
int ans=1,pos=lower_bound(L+1,L+n+2,Le)-L;
if (pos>n||Ri<s[pos].R)
return 0;
for (int i=18;i>=0;i--){
if (!p[pos][i]||s[p[pos][i]].R>Ri)
continue;
pos=p[pos][i];
ans+=1<<i;
}
return ans;
}
int main(){
scanf("%d",&n),rn=n;
for (int i=1;i<=n;i++){
scanf("%d%d",&s[i].L,&s[i].R);
Hash[++hs]=s[i].L;
Hash[++hs]=s[i].R;
}
HASH();
for (int i=1;i<=n;i++){
s[i].L=lower_bound(Hash+1,Hash+hs+1,s[i].L)-Hash;
s[i].R=lower_bound(Hash+1,Hash+hs+1,s[i].R)-Hash;
}
Delete();
Get_Pos();
printf("%d\n",Get_Ans(1,hs));
S.clear();
S.insert(Inf),S.insert(-Inf);
bool empty_block=0;
for (int i=1;i<=rn;i++){
int now=*S.lower_bound(s2[i].L);
if (now==Inf||!vis[now]){
if (now<=s2[i].R)
continue;
int left=*--S.lower_bound(s2[i].L);
int right=*S.lower_bound(s2[i].R);
int val=Get_Ans(left+1,s2[i].L-1)+1+Get_Ans(s2[i].R+1,right-1);
if (val<Get_Ans(left+1,right-1))
continue;
S.insert(s2[i].L);
S.insert(s2[i].R);
if (s2[i].L!=s2[i].R)
vis[s2[i].R]=1;
if (empty_block)
putchar(' ');
printf("%d",i);
empty_block=1;
}
}
return 0;
}
BZOJ1178 [Apio2009]CONVENTION会议中心 贪心 set的更多相关文章
- bzoj1178 [Apio2009]CONVENTION会议中心 区间dp+贪心
[Apio2009]CONVENTION会议中心 Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 1130 Solved: 444[Submit][S ...
- BZOJ1178 [Apio2009]CONVENTION会议中心
本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转载请注明出处,侵权必究,保留最终解释权! Description Siruseri政府建造了 ...
- 【BZOJ-1178】CONVENTION会议中心 倍增 + set (神思路好题!)
1178: [Apio2009]CONVENTION会议中心 Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 812 Solved: 323[Subm ...
- 1178: [Apio2009]CONVENTION会议中心
1178: [Apio2009]CONVENTION会议中心 https://lydsy.com/JudgeOnline/problem.php?id=1178 分析: set+倍增. 首先把所有有包 ...
- 【bzoj1178】 Apio2009—CONVENTION会议中心
http://www.lydsy.com/JudgeOnline/problem.php?id=1178 (题目链接) 题意 给出n个区间,问在区间两两不相交的情况下最多能选出多少区间,并输出字典序最 ...
- bzoj 1178: [Apio2009]CONVENTION会议中心(少见做法掉落!)【贪心+二分】
数组若干+手动二分一个的算法,bzoj rank8 ===============================废话分割线=================================== 我我 ...
- bzoj 1178 [Apio2009]CONVENTION会议中心
这题好难啊! 我好菜啊! 思路:对于最多线段不相交, 我们可以按左端点sort之后,贪心取. 但是这个题要求选取的线段排序之后序号的字典序最小. 那么我们如果按序号贪心地从大往小往里放, 那么对于第k ...
- 【BZOJ】【1178】【APIO2009】convention会议中心
贪心 如果不考虑字典序的话,直接按右端点排序,能选就选,就可以算出ans…… 但是要算一个字典序最小的解就比较蛋疼了= = Orz了zyf的题解 就是按字典序从小到大依次枚举,在不改变答案的情况下,能 ...
- BZOJ1178 APIO2009 会议中心 贪心、倍增
传送门 只有第一问就比较水了 每一次贪心地选择当前可以选择的所有线段中右端点最短的,排序之后扫一遍即可. 考虑第二问.按照编号从小到大考虑每一条线段是否能够被加入.假设当前选了一个区间集合\(T\), ...
随机推荐
- Java基础编程题——素数
package com.yangzl.basic; /** * 判断101-200之间有多少个素数,并输出所有素数. * @author Administrator * */ /*程序分析:判断素数的 ...
- android 短信拦截
android 4+版本需要用户主动添加broadReceiver 1.清单文件 <manifest xmlns:android="http://schemas.android.com ...
- nginx 全局配置
nginx 全局配置 #user nobody; # user 主模块 ,指定nginx worker 进程的运行用户组 worker_processes ; # worker_processes 开 ...
- JavaScript之子类构建工具
(function(){ var initializing = false; var superPattern = /xyz/.test(function(){ xyz; }) ? /\b_super ...
- py-faster-rcnn + opencv3.0.0 + ubuntu16.04配置(CPU模式)
最近开始做行人检测,因此开始接触faster-rcnn,这里贴上配置教程(亲测可行),不过是基于cpu的,蓝瘦... 参考博客:http://www.tuicool.com/articles/nYJr ...
- python实战===教你用微信每天给女朋友说晚安
但凡一件事,稍微有些重复.我就考虑怎么样用程序来实现它. 这里给各位程序员朋友分享如何每天给朋友定时微信发送”晚安“,故事,新闻,等等··· ···最好运行在服务器上,这样后台挂起来更方便. 准备: ...
- dubbo系列三、架构介绍及各模块关系
一.整体设计 图例说明: 图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口,位于中轴线上的为双方都用到的接口. 图中从下至上分为十层,各层均为单向依赖,右边的黑色箭头代 ...
- 『实践』Yalmip获取对偶函数乘子
『实践』Yalmip获取对偶函数乘子 一.sdpsetting设置 Yalmip网站给出的说明 savesolveroutput默认为0,需要设置为1才会保存输出结果. 下面是我模型的约束个数: 二. ...
- git安装及基础用法
1.安装GitGit-2.9.3-64-bit.exe 2.打开Git Bash,设置用户名,Email $ git config --global user.name "Your Name ...
- igmp组播测试环境搭建
2.4G无线组播测试环境搭建: (1)组播源: VLC 或者 pixstream (2)无线: 2.4G AP (3)客户端PC: VLC播放器 有线直连 无线2.4G PC(组播源pixstream ...