[SHOI2009]Booking 会场预约
2024-08-31 13:39:19
题目:洛谷P2161。
题目大意:有一些操作,分为两种:
A.增加一个从第l天到第r天的预约,并删除与这个预约冲突的其他预约,输出删除了多少个预约。
B.输出当前有效预约个数。
两个预约冲突定义为两个预约有公共的日期。
解题思路:本题可以用STL巧妙解决。
首先要知道,STL中的lower_bound返回范围内第一个大于等于要查找的值的指针。
以下用区间来表示预约,[l,r]就表示第l天到第r天的预约。
首先建立结构体,l和r表示区间的左端点和右端点。
用set保存每个区间,比较方法为:按照r为第一关键字,小的在前,然后按照l为第二关键字,大的在前。
然后对于每个A操作,我们在set里用lower_bound查找[0,l],返回的其实是原有区间中,右端点最小的,且大于等于当前区间左端点的一个区间。
然后比较一下查到的区间的左端点是否小于当前区间的右端点。
如果是,则删除这个区间,答案+1,并重复这个过程。
否则,因为查找到的区间严格大于当前区间(即没有冲突,且l和r都大于当前的l和r),那么下一个区间就严格大于查找到的区间,而当前区间的左端点大于上一个区间的右端点(或没有上一个区间),所以没有剩下的冲突了,结束查找,插入当前区间并输出答案。
对于B操作,只需输出set的size即可。
时间复杂度$O(n\log^2 n)$。
另外set自带lower_bound,范围默认为整个容器。
C++ Code:
#include<set>
#include<cstdio>
#include<algorithm>
#include<cctype>
using namespace std;
struct hy{
int l,r;
bool operator <(const hy&rhs)const{
if(r!=rhs.r)return r<rhs.r;
return l<rhs.l;
}//以右端点为第一关键字,左端点为第二关键字
};
set<hy>s;
inline int readint(){
char c=getchar();
for(;!isdigit(c);c=getchar());
int d=0;
for(;isdigit(c);c=getchar())
d=(d<<3)+(d<<1)+(c^'0');
return d;
}
int main(){
set<hy>::iterator it;
for(int t=readint();t--;){
char c=getchar();
while(!isalpha(c))c=getchar();
if(c=='A'){
int l=readint(),r=readint(),ans=0;
it=s.lower_bound((hy){0,l});
while(it!=s.end()&&r>=it->l){
++ans;
s.erase(it);
it=it=s.lower_bound((hy){0,l});
}
printf("%d\n",ans);
s.insert((hy){l,r});
}else printf("%u\n",s.size());
}
return 0;
}
好像在洛谷上跑了Rank1耶!
最新文章
- Go语言学习笔记1 变量,类型以及赋值
- webdriver对象定位方法
- hdu 4764 Stone (巴什博弈,披着狼皮的羊,小样,以为换了身皮就不认识啦)
- android MotionEvent中getX()和getRawX()的区别
- 【Linux安全】chattr命令锁定账户敏感文件
- mongodb基本概念解析
- python 安装中的错误解决
- 关于控制下拉框只读的js控制
- Java设计模式——模板方法模式
- 管理和安装 chart - 每天5分钟玩转 Docker 容器技术(168)
- ShortcutBadgerDemo【安卓应用角标(badge)实现方案】
- JavaScript基础-3
- AES加密解密算法
- [干货教程]仿网易云课堂微信小程序开发实战经验
- [学习笔记]Dsu On Tree
- 复习python
- html:meta
- 【刷题】BZOJ 3944 Sum
- 快速排序C++实现
- dataTable配置项说明