会场预约

题目描述

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\n",ans[i]);
        else         printf("%d\n",sum);
    } 
    return 0;
}

 

posted @ 2017-08-05 20:45  浪矢-CL  阅读(443)  评论(0编辑  收藏  举报