P2161 [SHOI2009]会场预约 (线段树:线段树上的不重复覆盖数)
题目描述
PP大厦有一间空的礼堂,可以为企业或者单位提供会议场地。这些会议中的大多数都需要连续几天的时间(个别的可能只需要一天),不过场地只有一个,所以不同的会议的时间申请不能够冲突。也就是说,前一个会议的结束日期必须在后一个会议的开始日期之前。所以,如果要接受一个新的场地预约申请,就必须拒绝掉与这个申请相冲突的预约。 一般来说,如果PP大厦方面事先已经接受了一个会场预约,例如从10日到15日,就不会在接受与之相冲突的预约,例如从12日到17日。不过,有时出于经济利益,PP大厦方面有时会为了接受一个新的会场预约,而拒绝掉一个甚至几个之前预订的预约。 于是,礼堂管理员QQ的笔记本上笔记本上经常记录着这样的信息: 本题中为方便起见,所有的日期都用一个整数表示。例如,如果一个为期10天的会议从“90日”开始到“99日”,那么下一个会议最早只能在“100日”开始。 最近,这个业务的工作量与日俱增,礼堂的管理员QQ希望参加SHTSC的你替他设计一套计算机系统,方便他的工作。这个系统应当能执行下面两个操作: A操作:有一个新的预约是从“start日”到“end日”,并且拒绝掉所有与它相冲突的预约。执行这个操作的时候,你的系统应当返回为了这个新预约而拒绝掉的预约个数,以方便QQ与自己的记录相校对。 B操作:请你的系统返回当前的仍然有效的预约的总数。
输入输出格式
输入格式:
输入文件的第一行是一个整数n,表示你的系统将接受的操作总数。 接下去n行每行表示一个操作。每一行的格式为下面两者之一: “A start end”表示一个A操作; “B”表示一个B操作。
输出格式:
输出文件有n行,每行一次对应一个输入。表示你的系统对于该操作的返回值。
输入输出样例
6
A 10 15
A 17 19
A 12 17
A 90 99
A 11 12
B
0
0
2
0
1
2
说明
N< = 200000
1< = Start End < = 100000
进入正题
先把题目看成一个仅实现区间修改的线段树,用tagtag数组打打标记即可 这是基础啊对吧qwq
为了方便我描述理解,以下把预约序号看成颜色
A操作的真实目的:查询一个区间中有多少种颜色,然后清空数列中所有在该区间中出现的颜色,最后把这个区间修改成另一种颜色 (先别急着看B操作qwq)
简而言之就是查询->清空->修改
对于查询操作,我们可以引入findfind函数和samesame数组。findfind函数的职能是遍历给定区间。当same[o]==1same[o]==1时,该区间内只有一种颜色,这时就可以得知该区间的颜色了;否则继续向下遍历。
对于清空操作:其实不用真的清空,只需要引入一个deldel数组,存储该颜色是否已被删除即可
对于修改,不在话下这是基础啊对吧qwq
对于B操作.....,用一个ansans储存还剩几种颜色未被删除,然后就没有然后了
应该在线离线都支持,不过离线的话可以用st,edst,ed存线段树的左右端点,建的树小(当然在线的话直接开到最大对吧)
复杂度大概O(nlogn)O(nlogn)吧原谅我不太会算(逃
#include<bits/stdc++.h> using namespace std ; #define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1 const int maxn = ;
int ans,era,v,n,st=0x3f3f3f3f,en=-0x3f3f3f3f;
bool same [maxn],del[maxn];
int tag[maxn];
struct no
{
int l,r;
char op[];
}a[maxn];
void build(int l , int r , int rt)
{
same[rt]=;tag[rt]=;//记得初始化:刚开始的树无修改标记且整棵树都只有一个颜色(无色==0)
if(l==r) return ;
int mid=(l+r)>>;
build(lson);
build(rson); } void find(int l , int r , int rt)
{
if(same[rt]==)
{
if(!del[tag[rt]] && tag[rt])//有颜色,这个颜色没有被桑过了拉
{
--ans;
++era;//用ans记录还剩几种颜色,era记录这次删除了几种颜色(注意判无色
}
del[tag[rt]]=;//删除
tag[rt]=v;//修改
return ;
}
int mid=(l+r)>>;
find(lson);
find(rson);
tag[rt]=v;
same[rt]=;//这个区间都是一样的颜色
}
void pushdown(int l , int r , int rt)///标记下传
{
same[rt]=;//可以下传肯定这个区间不是同色
if(!tag[rt])
return ;
tag[rt<<]=tag[rt<<|]=tag[rt];
tag[rt]=;
}
void update(int L , int R , int l , int r , int rt)
{
if(L<=l&&r<=R)
{
find(l,r,rt);//加入一个find函数对所求区间进行更深一层的遍历
return ;
}
pushdown(l,r,rt);
int mid=(l+r)>>;
if(L<=mid)
update(L,R,lson);
if(R>mid)
update(L,R,rson); } int main( )
{
scanf("%d",&n);
for(int i= ; i<=n ; i++)
{
scanf("%s",a[i].op);
if(a[i].op[]=='B')
continue;
scanf("%d%d",&a[i].l,&a[i].r);
st=min(st,a[i].l);
en=max(en,a[i].r);
}
build(st,en,);
int cnt = ;///当前颜色的标号
for(int i= ; i<=n ; i++)
{
if(a[i].op[]=='A')
{ ++ans;
v=++cnt ; era=;
update(a[i].l,a[i].r,st,en,);
printf("%d\n",era);
}else
printf("%d\n",ans);
}
return ;
}
P2161 [SHOI2009]会场预约 (线段树:线段树上的不重复覆盖数)的更多相关文章
- 【题解】P2161[SHOI2009]会场预约(set)
[题解][P2161 SHOI2009]会场预约 题目很像[[题解]APIO2009]会议中心 \(set\)大法好啊! 然后我们有个小\(trick\)(炒鸡帅),就是如何优雅地判断线段交? str ...
- P2161 [SHOI2009]会场预约[线段树/树状数组+二分/STL]
题目描述 PP大厦有一间空的礼堂,可以为企业或者单位提供会议场地.这些会议中的大多数都需要连续几天的时间(个别的可能只需要一天),不过场地只有一个,所以不同的会议的时间申请不能够冲突.也就是说,前一个 ...
- P2161 [SHOI2009]会场预约
题目描述 PP大厦有一间空的礼堂,可以为企业或者单位提供会议场地.这些会议中的大多数都需要连续几天的时间(个别的可能只需要一天),不过场地只有一个,所以不同的会议的时间申请不能够冲突.也就是说,前一个 ...
- [洛谷P2161][SHOI2009]会场预约
题目大意:有两种操作: $A\;l\;r:$表示加入区间$[l,r]$,并把与之冲突的区间删除,输出删除的区间的个数,区间$A$于区间$B$冲突当且仅当$A\cap B\not=\varnothing ...
- [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 ...
- Luogu2161 [SHOI2009]会场预约-线段树
Solution 线段树维护 sum 表示区间内预约个数, L 表示区间最左边的预约, R 表示区间最右边的预约. $pushup$ 就是这样 : void up(int nd) { sum[nd] ...
- BZOJ2028:[SHOI2009]会场预约(线段树版)
浅谈树状数组与线段树:https://www.cnblogs.com/AKMer/p/9946944.html 题目传送门:https://www.lydsy.com/JudgeOnline/prob ...
- BZOJ_3307_雨天的尾巴_线段树合并+树上差分
BZOJ_3307_雨天的尾巴_线段树合并 Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y 对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成 所有发放后 ...
随机推荐
- ACM学习历程—HDU5521 Meeting(图论)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5521 学习菊苣的博客,只粘链接,不粘题目描述了. 题目大意就是一个人从1开始走,一个人从n开始走.让最 ...
- bzoj 1069: [SCOI2007]最大土地面积 凸包+旋转卡壳
题目大意: 二维平面有N个点,选择其中的任意四个点使这四个点围成的多边形面积最大 题解: 很容易发现这四个点一定在凸包上 所以我们枚举一条边再旋转卡壳确定另外的两个点即可 旋(xuan2)转(zhua ...
- Access中复制表
很多时候在Access中需要复制表,或只复制结构,源表名:a: 新表名:b (经测试中Access可用) 法一:select * into b from a where 1<>1 ...
- UDEV管理RAC共享存储
背景:操作系统 centos 6.7 数据库:11.2.0.1 操作流程: 1. 确认在所有RAC节点上已经安装了必要的UDEV包[root@11gnode1 ~]# rpm -qa|grep ude ...
- bzoj 3671 随机数生成器 —— 暴力
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3671 原来256M是可以开两个3e7的数组的: 因为答案只有 n+m-1 个数,所以暴力判断 ...
- 【转】 Pro Android学习笔记(二二):用户界面和控制(10):自定义Adapter
目录(?)[-] 设计Adapter的布局 代码部分 Activity的代码 MyAdapter的代码数据源和构造函数 MyAdapter的代码实现自定义的adapter MyAdapter的代码继续 ...
- 【转】 Pro Android学习笔记(二一):用户界面和控制(9):Gallery和SimpleAdapter
Gallery画廊式控件,如图所示,但是在API level 16,也即Android 4.1,被deprecated,可以使用HorizontableScroolView和ViewPager.但是后 ...
- Linux统计文件夹占用空间大小--du命令基本用法
命令行环境下要知道linux系统里一个文件夹以及其包含的文件实际所占用的空间大小,linux自带的命令 du可以很好地满足需求. 其他的用法我就不一一写出来了,就列本人觉得会用得最多的,直接上: $ ...
- java基础知识学习 java异常
1: Unchecked Exception( 也就是运行时异常) VS Check Exception(非运行时异常) 2: 运行期异常 VS 非运行期异常? 非运行时异常: 必须在代码中显示 ...
- 又来一波!Android精品源码分享
今天又汇总了几个不错的源码给大家!希望能帮到需要的小伙伴~话不多少,直接上源码! 1.Android精品源码:拖动条控件实现源码 此次分享的源码是一个不错的Android控件,建议大家可以细致的看下. ...