P3626 [APIO2009]会议中心

题目描述

Siruseri 政府建造了一座新的会议中心。许多公司对租借会议中心的会堂很 感兴趣,他们希望能够在里面举行会议。

对于一个客户而言,仅当在开会时能够独自占用整个会堂,他才会租借会堂。 会议中心的销售主管认为:最好的策略应该是将会堂租借给尽可能多的客户。

显 然,有可能存在不止一种满足要求的策略。 例如下面的例子。总共有 4 个公司。他们对租借会堂发出了请求,并提出了 他们所需占用会堂的起止日期(如下表所示)。

       开始日期 结束日期
公司1 4 9
公司2 9 11
公司3 13 19
公司4 10 17

上例中,最多将会堂租借给两家公司。租借策略分别是租给公司 1 和公司 3, 或是公司 2 和公司 3,也可以是公司 1 和公司 4。注意会议中心一天最多租借给 一个公司,所以公司 1 和公司 2 不能同时租借会议中心,因为他们在第九天重合 了。

销售主管为了公平起见,决定按照如下的程序来确定选择何种租借策略:首 先,将租借给客户数量最多的策略作为候选,将所有的公司按照他们发出请求的 顺序编号。对于候选策略,将策略中的每家公司的编号按升序排列。最后,选出 其中字典序最小1的候选策略作为最终的策略。

例中,会堂最终将被租借给公司 1 和公司 3:3 个候选策略是 {(1,3),(2,3),(1,4)}。而在字典序中(1,3)<(1,4)<(2,3)。 你的任务是帮助销售主管确定应该将会堂租借给哪些公司。

输入输出格式

输入格式:

输入的第一行有一个整数 N,表示发出租借会堂申请的公司的个数。第 2 到 第 N+1 行每行有 2 个整数。第 i+1 行的整数表示第 i 家公司申请租借的起始和终 止日期。对于每个公司的申请,起始日期为不小于 1 的整数,终止日期为不大于 10^9 的整数。

输出格式:

输出的第一行应有一个整数 M,表示最多可以租借给多少家公司。第二行应列出 M 个数,表示最终将会堂租借给哪些公司。

输入输出样例

输入样例#1: 复制

4

4 9

9 11

13 19

10 17

输出样例#1: 复制

2

1 3

说明

对于 50%的输入,N≤3000。

在所有输入中,N≤200000。


题解

先让我吐槽一波。

今天教练给我们考倍增NOIP(Professional)模拟的考试题目。

第一题就是这一题,就第二题LCA模板????

3,4都是NOI原题。肝了一下午。真棒。

接下来讲题解了。

考场上我想的是把一个线段的左端点排序。我不会告诉你我是从 \(1\) 跳到 \(n\)的

从 \(n\) 遍历到 \(1\) 然后二分最靠近它右端点的另一个线段的左端点。然后如果能跳到 \(i-1\) 的个数小于 \(i\),那么就把 \(i-1\) 的信息都更新为 \(i\) 的,不然则把 \(i\) 的总值同等于 \(i-1\)。

这样的话我们就能在\(O(nlogn)\)的时间复杂度内搞出第一问了。

但是第二问怎么搞啊。

很明显的一个贪心:当我可以从多个线段跳过来的时候,我肯定是选择那个字典序最小的,那么,我就只需要在发现 \(i\) 的总值和 \(i-1\) 的总值相等时加一个暴力维护一下就好了,不相等就暴力更新。

时间复杂度是玄学的,可以被卡。但是X谷上还是跑的挺快的。


代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=200001;
const int fuck=99999999;
struct node{
int l,r,id;
}ch[N];
int n,m,ans,cnt;
int sum[N],pre[N],now=99999999,line[N],minn[N],nn;
int read()
{
int x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*w;
} bool cmp(node a,node b){
return a.l<b.l;
} bool cmp2(node a,node b){
return a.id<b.id;
} int find (int x){
int l=1,r=n,ans=0;
while(r>l){
int mid=(l+r)>>1;
if(ch[mid].l>x)r=mid,ans=mid;
else l=mid+1;
}
return r;
} bool judge(int x,int y){
int a=fuck,b=fuck;
while(x!=y){
a=min(ch[x].id,a);b=min(ch[y].id,b);
x=pre[x];y=pre[y];
}
return a<b;
} void solve()
{
for(int i=n;i>=1;i--){
int next=find(ch[i].r);
sum[i]=1;minn[i]=i;pre[i]=fuck;
if(ch[next].l>ch[i].r)sum[i]=sum[next]+1,pre[i]=minn[next];
if(i!=n){
if(sum[i+1]>sum[i])
sum[i]=sum[i+1],minn[i]=minn[i+1],pre[i]=pre[i+1];
if(sum[i+1]==sum[i]&&judge(minn[i+1],minn[i]))
sum[i]=sum[i+1],minn[i]=minn[i+1],pre[i]=pre[i+1];
}
ans=max(ans,sum[i]);
}
cout<<ans<<endl;
int x=minn[1];
while(x!=fuck){
line[++cnt]=ch[x].id;
x=pre[x];
}
sort(line+1,line+cnt+1);
for(int i=1;i<=cnt;i++)
cout<<line[i]<<' ';
} int main()
{
// freopen("interval.in","r",stdin);
// freopen("interval.out","w",stdout);
memset(minn,0x7f,sizeof(minn));
n=read();
for(int i=1;i<=n;i++)pre[i]=fuck;
for(int i=1;i<=n;i++){
ch[i].l=read();ch[i].r=read();ch[i].id=i;
}
sort(ch+1,ch+n+1,cmp);
solve();
return 0;
}

[APIO2009]会议中心(贪心)的更多相关文章

  1. BZOJ.1178.[APIO2009]会议中心(贪心 倍增)

    BZOJ 洛谷 \(Description\) 给定\(n\)个区间\([L_i,R_i]\),要选出尽量多的区间,并满足它们互不相交.求最多能选出多少个的区间以及字典序最小的方案. \(n\leq2 ...

  2. BZOJ1178 APIO2009 会议中心 贪心、倍增

    传送门 只有第一问就比较水了 每一次贪心地选择当前可以选择的所有线段中右端点最短的,排序之后扫一遍即可. 考虑第二问.按照编号从小到大考虑每一条线段是否能够被加入.假设当前选了一个区间集合\(T\), ...

  3. [APIO2009]会议中心

    [APIO2009]会议中心 题目大意: 原网址与样例戳我! 给定n个区间,询问以下问题: 1.最多能够选择多少个不相交的区间? 2.在第一问的基础上,输出字典序最小的方案. 数据范围:\(n \le ...

  4. 【题解】[APIO2009]会议中心

    [题解][P3626 APIO2009]会议中心 真的是一道好题!!!刷新了我对倍增浅显的认识. 此题若没有第二份输出一个字典序的方案,就是一道\(sort+\)贪心,但是第二问使得我们要用另外的办法 ...

  5. BZOJ1178 [Apio2009]CONVENTION会议中心 贪心 set

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1178 题意概括 一堆线段,现在取出最多条数,使其互不覆盖,并输出字典序最小的方案. 题解 这题好坑 ...

  6. BZOJ1178或洛谷3626 [APIO2009]会议中心

    BZOJ原题链接 洛谷原题链接 第一个问题是经典的最多不相交区间问题,用贪心即可解决. 主要问题是第二个,求最小字典序的方案. 我们可以尝试从\(1\to n\)扫一遍所有区间,按顺序对每一个不会使答 ...

  7. Luogu 3626 [APIO2009]会议中心

    很优美的解法. 推荐大佬博客 如果没有保证字典序最小这一个要求,这题就是一个水题了,但是要保证字典序最小,然后我就不会了…… 如果一条线段能放入一个区间$[l', r']$并且不影响最优答案,那么对于 ...

  8. P3626 [APIO2009]会议中心

    传送门 好迷的思路-- 首先,如果只有第一问就是个贪心,排个序就行了 对于第二问,我们考虑这样的一种构造方式,每一次都判断加入一个区间是否会使答案变差,如果不会的话就将他加入别问我正确性我不会证 我们 ...

  9. [Luogu P3626] [APIO2009] 会议中心

    题面 传送门:https://www.luogu.org/problemnew/show/P3626 Solution 如果题目只要求求出第一问,那这题显然就是大水题. 但是加上第二问的话...... ...

随机推荐

  1. Sql Server创建主键失败:CREATE UNIQUE INDEX 终止,因为发现对象名称 '[PPR_BasicInformation]' 和索引名称 '[PK_PPR_BasicInformation]' 有重复的键(E)

    这种问题是由于主键设置了唯一性,而数据库中主键列的值又有重复的值,重复值为E,改掉其中一个值就可以了.

  2. 【原创】JMS生产者和消费者【PTP异步接收消息】

    PTP模式下,异步接收消息需要定义一个MessageListener来监听,当生产者有消息要发送时会主动通知Listener去处理该消息,会调用监听的onMessage方法去处理. 首先看生产者(和同 ...

  3. 【原创】websphere部署war包报错

    应用程序在Tomcat上运行一切正常,但在websphere上部署时报以下错误:错误 500 处理请求时发生一个错误: /admin/upload.do 消息: WEB-INF/web.xml 详细错 ...

  4. 由Request Method:OPTIONS初窥CORS(转)

    刚接触前端的时候,以为HTTP的Request Method只有GET与POST两种,后来才了解到,原来还有HEAD.PUT.DELETE.OPTIONS…… 目前的工作中,HEAD.PUT.DELE ...

  5. JZOJ5787轨道(容斥+DP)

    JZOJ5787轨道 Description 2018年1月31日,152年一遇的超级大月全食在中国高空出现(没看到的朋友真是可惜),小B看到月食,便对月球的轨道产生了兴趣.他上网查重力加速度的公式, ...

  6. 紫书 习题8-8 UVa 1612 (贪心+精度)

    这道题我很快就写出来了, 但是一直WA, 然后发现是精度, 这坑了我一个小时-- (1)贪心.每次就尽量分数高, 可以保证最后分数最高 (2)神tm精度问题.记住判断大于小于和等于的时候要用EPS(1 ...

  7. C#-类 字段 属性 方法 特性

    方法的签名 包括参数个数.参数类型.方法返回值 base和this关键字 1.使用base关键字,就可以使用父类中的字段.属性.方法 2.一旦父类中存在有参数的构造函数,那么子类就必须使用base来覆 ...

  8. 洛谷 P2730 魔板 Magic Squares

    P2730 魔板 Magic Squares 题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题目描述 ...

  9. android获取自己定义控件位置坐标,屏幕尺寸,标题栏,状态栏高度

    android获取自己定义控件位置坐标,屏幕尺寸,标题栏,状态栏高度 1.获取自己定义控件height 在本Activity中获取当前Activity中控件的height: Button button ...

  10. GetKeyState(), GetAsyncKeystate(), GetKeyboardSlate()

    GetKeyState.GetAsyncKeyState.GetKeyboardState函数的差别: 1.BOOL GetKeyboardState( PBYTE lpKeyState );获得全部 ...