售票系统

247. 售票系统

★★☆   输入文件: railway.in   输出文件: railway.out    简单对比
时间限制:1 s   内存限制:128 MiB

【问题描述】

某次列车途经C个城市,城市编号依次为1到C,列车上共有S个座位,铁路局规定售出的车票只能是坐票, 即车上所有的旅客都有座。售票系统是由计算机执行的,每一个售票申请包含三个参数,分别用O、D、N表示,O为起始站,D为目的地站,N为车票张数。售票 系统对该售票申请作出受理或不受理的决定,只有在从O到D的区段内列车上都有N个或N个以上的空座位时该售票申请才被受理。请你写一个程序,实现这个自动 售票系统。

【输入格式】

第一行包含三个用空格隔开的整数C、S和R,其中1≤C≤60000, l≤S≤60000,1≤R≤60000。C为城市个数,S为列车上的座位数,R为所有售票申请总数。接下来的R行每行为一个售票申请,用三个由空格隔开的整数O,D和N表示,O为起始站,D 为目的地站,N为车票站数,其中1≤D≤C,1≤O≤C,所有的售票申请按申请的时间从早到晚给出。

【输出格式】

输出共有R行,每行输出一个“YES”或“NO”,表示当前的售票申请被受理或不被受理。

【输入输出样例】

输入:

4 6 4

1 4 2

1 3 2

2 4 3

1 2 3

输出:

YES

YES

NO

NO

线段树 lazy 标记。。关键还是处理好标记。什么时候下放。什么时候回放。在更新的时候,更新一个区间的值时,那么这么区间的总个数已经加过。所以下次操作只需要增加这个区间的子树就可以了。同时还要更新父亲节点。

下面是AC代码:

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 60000+10;
struct node{
    int l,r;
    int tot;
    int lazy;
}T[maxn<<2];
int s;
void build(int id,int l,int r){
    T[id].l=l; T[id].r=r; T[id].tot=0;T[id].lazy=0;
    if(l==r) return;
    int m=(l+r)>>1;
    build(id<<1,l,m); build(id<<1|1,m+1,r);
}
void update(int id,int l,int r,int n){
     if(T[id].l==l&&T[id].r==r){
         T[id].lazy+=n;  T[id].tot+=n;  return ;
     }
      if(T[id].lazy!=0){
        T[id<<1].tot+=T[id].lazy; T[id<<1|1].tot+=T[id].lazy;
        T[id<<1].lazy+=T[id].lazy; T[id<<1|1].lazy+=T[id].lazy;
        T[id].lazy=0;
     }
     int m=(T[id].l+T[id].r)>>1;
     if(m>=r)   update(id<<1,l,r,n);
     else  if( l>m)    update(id<<1|1,l,r,n);
     else{
       update(id<<1,l,m,n);
       update(id<<1|1,m+1,r,n);
     }
     T[id].tot=max(T[id<<1].tot,T[id<<1|1].tot);
}
int query(int id,int l,int r){
    if(T[id].l==l&&T[id].r==r) return T[id].tot;
     if(T[id].lazy!=0){
        T[id<<1].tot+=T[id].lazy; T[id<<1|1].tot+=T[id].lazy;
        T[id<<1].lazy+=T[id].lazy; T[id<<1|1].lazy+=T[id].lazy;
        T[id].lazy=0;
    }
    int m=(T[id].l+T[id].r)>>1;
    if(m>=r) return  query(id<<1,l,r);
    else  if( l>m)  return  query(id<<1|1,l,r);
    else{
       return   max(query(id<<1,l,m),query(id<<1|1,m+1,r));
    }
}
int main(){
    freopen("railway.in","r",stdin);
    freopen("railway.out","w",stdout);
    int c,r;
    int left,right,n;
    scanf("%d%d%d",&c,&s,&r);
    build(1,1,c+1);
    for(int i=0;i<r;i++){
        scanf("%d%d%d",&left,&right,&n);  right--;
        int sum=query(1,left,right);
        if(s-sum>=n)   update(1,left,right,n),     puts("YES");
        else                                     puts("NO");
    }
    return 0;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值