题目描述
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
Day2
思路:
离线操作,倒着处理。
#include<iostream> #include<queue> #include<cstdio> #include<math.h> #include<cstring> #include<algorithm> using namespace std; #define M 100000 int l[M*4],r[4*M],ans[M*4]; int minn[M*4+9],lazy[M*4+9]; int tot=0,n; void set(int id) { lazy[id<<1]=min(lazy[id<<1],lazy[id]); minn[id<<1]=min(minn[id<<1],lazy[id<<1]); lazy[id<<1|1]=min(lazy[id<<1|1],lazy[id]); minn[id<<1|1]=min(minn[id<<1|1],lazy[id<<1|1]); } void add(int l,int r,int id,int tl,int tr,int x) { if(tl<=l&&r<=tr) { lazy[id]=min(x,lazy[id]); minn[id]=lazy[id]; return ; } if(lazy[id] != M*9) set(id); int mid=(l+r)>>1; if(tl<=mid) add(l,mid,id<<1,tl,tr,x); if(tr>=mid+1) add(mid+1,r,id<<1|1,tl,tr,x); minn[id]=min(minn[id<<1],minn[id<<1|1]); return; } int check(int l,int r,int id ,int tl,int tr) { if(tl<=l&&r<=tr) return minn[id]; if(lazy[id] != M*9) set(id); int mid=(l+r)>>1,ans=9*M; if(tl<=mid) ans=min(ans,check(l,mid,id<<1,tl,tr)); if(tr>=mid+1) ans=min(ans,check(mid+1,r,id<<1|1,tl,tr)); return ans; } int main() { scanf("%d",&n);char c; for(int i=1;i<=M*3;i++) minn[i]=lazy[i]=9*M; for(int i=1;i<=n;i++) { cin>>c; if(c=='A') scanf("%d%d",&l[i],&r[i]); } for(int i=n;i>=1;i--) if(l[i]) { tot=check(1,M,1,l[i],r[i]); if(tot!=M*9) ans[tot]++; add(1,M,1,l[i],r[i],i); } int sum=0; for(int i=1;i<=n;i++) { if(l[i]) sum=sum+1-ans[i],printf("%d ",ans[i]); else printf("%d ",sum); } return 0; }