BZOJ2028:[SHOI2009]会场预约(线段树版)
浅谈树状数组与线段树:https://www.cnblogs.com/AKMer/p/9946944.html
题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=2028
这题一开始我只会平衡树写法,打死都想不出线段树怎么写。然后偷偷去瞄一眼题解,里面说到了线段树染色。然后就一直往这个方向想。发现这就是区间赋值,对于第\(i\)个区间全部赋值成\(i\)就行了……然后对于每个区间有多少个不同的颜色段怎么更新又成了问题。我们记录一下每个区间最左边和最右边的颜色,合并的时候看看中间能不能拼上就行了。对于每次新的预约,与\(l\)或\(r\)相交的区间直接强行擦去(用\(0\)号颜色覆盖),然后再全部覆盖新的颜色。
时间复杂度:\(O(nlog10^5)\)
空间复杂度:\(O(10^5)\)
代码如下:
#include <cstdio>
using namespace std;
const int maxn=2e5+5;
int n;
char s[10];
int st[maxn],ed[maxn];
int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
struct segment_tree {
int num[maxn<<2],lft[maxn<<2],rgt[maxn<<2],tag[maxn<<2];//num[i]记录i号区间内不同颜色的段数,lft记录i号区间最左边的颜色,rgt记录最右边的,tag为颜色覆盖标记
void push_down(int p) {
if(tag[p]!=-1) {
tag[p<<1]=lft[p<<1]=rgt[p<<1]=tag[p];
tag[p<<1|1]=lft[p<<1|1]=rgt[p<<1|1]=tag[p];
num[p<<1]=num[p<<1|1]=(tag[p]!=0);
tag[p]=-1;//下传标记,覆盖颜色
}
}
int query(int p,int l,int r,int pos) {
if(l==r)return lft[p];//递归到底了直接返回
if(lft[p]&&(lft[p]==rgt[p]))return lft[p];//如果整个区间都已经有颜色了就不需要递归了
int mid=(l+r)>>1;push_down(p);
if(pos<=mid)return query(p<<1,l,mid,pos);
return query(p<<1|1,mid+1,r,pos);
}
void updata(int p) {
num[p]=num[p<<1]+num[p<<1|1];//直接相加
if(rgt[p<<1]&&(rgt[p<<1]==lft[p<<1|1]))num[p]--;//如果中间的一样那就减一
lft[p]=lft[p<<1];rgt[p]=rgt[p<<1|1];//更新lft和rgt
}
void change(int p,int l,int r,int L,int R,int v) {
if(L<=l&&r<=R) {tag[p]=v;num[p]=(v!=0);lft[p]=rgt[p]=v;return;}//如过v不为0才算有颜色
int mid=(l+r)>>1;push_down(p);
if(L<=mid)change(p<<1,l,mid,L,R,v);
if(R>mid)change(p<<1|1,mid+1,r,L,R,v);
updata(p);
}
}T;
int main() {
n=read();
for(int i=1;i<=400000;i++)T.tag[i]=-1;//初始标记为-1,因为可能会有用0号颜色覆盖
for(int i=1;i<=n;i++) {
scanf("%s",s+1);
if(s[1]=='A') {
int l=read(),r=read();
st[i]=l;ed[i]=r;
int fake1=T.query(1,1,100000,l);
int fake2=T.query(1,1,100000,r);//fake1号预约与l相交,fake2与r相交
int tmp=T.num[1];
if(fake1)T.change(1,1,100000,st[fake1],ed[fake1],0);
if(fake2)T.change(1,1,100000,st[fake2],ed[fake2],0);//擦去
T.change(1,1,100000,l,r,i);
tmp=tmp-T.num[1]+1;printf("%d\n",tmp);//之前有的预约减去现在的预约数减一就是拒绝的预约数
}
else printf("%d\n",T.num[1]);//1号结点覆盖了全部区间
}
return 0;
}
BZOJ2028:[SHOI2009]会场预约(线段树版)的更多相关文章
- P2161 [SHOI2009]会场预约[线段树/树状数组+二分/STL]
题目描述 PP大厦有一间空的礼堂,可以为企业或者单位提供会议场地.这些会议中的大多数都需要连续几天的时间(个别的可能只需要一天),不过场地只有一个,所以不同的会议的时间申请不能够冲突.也就是说,前一个 ...
- Luogu2161 [SHOI2009]会场预约-线段树
Solution 线段树维护 sum 表示区间内预约个数, L 表示区间最左边的预约, R 表示区间最右边的预约. $pushup$ 就是这样 : void up(int nd) { sum[nd] ...
- BZOJ2028:[SHOI2009]会场预约(平衡树版)
浅谈\(splay\):https://www.cnblogs.com/AKMer/p/9979592.html 浅谈\(fhq\)_\(treap\):https://www.cnblogs.com ...
- BZOJ2028: [SHOI2009]会场预约(set)
Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 425 Solved: 213[Submit][Status][Discuss] Description ...
- [LuoguP2161[ [SHOI2009]会场预约 (splay)
题面 传送门:https://www.luogu.org/problemnew/show/P2161 Solution splay 的确有线段树/树状数组的做法,但我做的时候脑残没想到 我们可以考虑写 ...
- 2021.12.08 [SHOI2009]会场预约(平衡树游码表)
2021.12.08 [SHOI2009]会场预约(平衡树游码表) https://www.luogu.com.cn/problem/P2161 题意: 你需要维护一个 在数轴上的线段 的集合 \(S ...
- 【题解】P2161[SHOI2009]会场预约(set)
[题解][P2161 SHOI2009]会场预约 题目很像[[题解]APIO2009]会议中心 \(set\)大法好啊! 然后我们有个小\(trick\)(炒鸡帅),就是如何优雅地判断线段交? str ...
- P2161 [SHOI2009]会场预约 (线段树:线段树上的不重复覆盖数)
题目描述 PP大厦有一间空的礼堂,可以为企业或者单位提供会议场地.这些会议中的大多数都需要连续几天的时间(个别的可能只需要一天),不过场地只有一个,所以不同的会议的时间申请不能够冲突.也就是说,前一个 ...
- P2161 [SHOI2009]会场预约
题目描述 PP大厦有一间空的礼堂,可以为企业或者单位提供会议场地.这些会议中的大多数都需要连续几天的时间(个别的可能只需要一天),不过场地只有一个,所以不同的会议的时间申请不能够冲突.也就是说,前一个 ...
随机推荐
- js错误: Unexpected number in JSON at position 2792 value里面有双引号怎么解决
源头 出现这个报错提示,大家从错误就可以看的出来,这就是json的错误,一般来说都是json格式出现了错误,本人遇到比较多的情况就是json字符串里面出现了一些会影响json格式的符号,这次出现这个 ...
- CentOS下安装python3.x版本
现在python都到了3.x版本,但是centos中自带的python仍然是2.7版本的,所以想把python换成3.x版本的. 但是这个地方有个坑,你要是直接编译安装了python3.x之后,估计你 ...
- Swift———a Glance(极客学院)笔记
http://www.swiftv.cn/course/hw4sysi7 本课程很短,加起来一个小时,适合作为一个快速了解. 两本书: apple官方<The Swift Programmi ...
- iOS 10 的杂碎资料
兼容iOS 10 资料整理笔记 1.Notification(通知) 自从Notification被引入之后,苹果就不断的更新优化,但这些更新优化只是小打小闹,直至现在iOS 10开始真正的进行大 ...
- python 基础 2.8 python练习题
python 练习题: #/usr/bin/python #coding=utf-8 #@Time :2017/10/26 9:38 #@Auther :liuzhenchuan #@File ...
- Runnable 和 Callable的区别
Runnable 与 Callable的区别: (1)Callable规定的方法是call(),Runnable规定的方法是run(). (2)Callable的任务执行后可返回值,而Runnable ...
- My97datepicker日期控件
转自:http://www.my97.net/dp/demo/index.htm 非常不错的一篇文章,介绍的很详细.感兴趣的朋友可以好好研究一下. 网上资源很多的,可以下一个来使用. 先说一下整个文件 ...
- 使用IntelliJ IDEA 15和Maven创建Java Web项目(转)
1. Maven简介 相对于传统的项目,Maven 下管理和构建的项目真的非常好用和简单,所以这里也强调下,尽量使用此类工具进行项目构建, 它可以管理项目的整个生命周期. 可以通过其命令做所有相关的工 ...
- Jaccard Similarity and Shingling
https://www.cs.utah.edu/~jeffp/teaching/cs5955/L4-Jaccard+Shingle.pdf https://www.cs.utah.edu/~jeffp ...
- Linux就该这么学--Shell脚本条件语句(二)
1.for条件语句 先读取多个不同的变量值,然后逐一执行同一组命令. 从列表文件中读取主机地址,逐个测试是否在线. 从ipadds.txt中读取主机地址后赋值给HLIST变量后逐个ping列表中的主机 ...