【cogs247】售票系统【线段树】

【问题描述】

某次列车途经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
题解:区间修改,区间查询最大值。当座位数减最大值小于所要求的票数时输出NO。其他输出YES.
#include<iostream>
#include<cstdio>
using namespace std;
int t[1000001],n,d,o,p[1000001],maxx,minn,s,R,c;
int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
inline void paint(int k,int l,int r,int v)
{
	t[k]+=v;
	if (t[k]>s) t[k]=s; 
	p[k]+=v;
}
inline void pushdown(int k,int l,int r)
{
	int mid;
	mid=(l+r)/2;
	paint(k*2,l,mid,p[k]);
	paint(k*2+1,mid+1,r,p[k]);
	p[k]=0;
}
inline void add(int k,int l,int r,int ll,int rr,int v)
{
	int mid;
	if (ll<=l&&r<=rr) 
	  {
		paint(k,l,r,v);
		return;
	  }
	mid=(l+r)/2;
	if (ll<=mid) add(k*2,l,mid,ll,rr,v);
	if (rr>mid) add(k*2+1,mid+1,r,ll,rr,v);
    t[k]=max(t[k*2],t[k*2+1]);
}
inline int qmax(int k,int l,int r,int ll,int rr)
{
	int mid,maxx(-1);
	if (ll<=l&&r<=rr) return t[k];
	pushdown(k,l,r);
	mid=(l+r)/2;
	if (ll<=mid) maxx=max(maxx,qmax(k*2,l,mid,ll,rr));
	if (rr>mid) maxx=max(maxx,qmax(k*2+1,mid+1,r,ll,rr));
    return maxx;
} 
int main()
{
	freopen("railway.in","r",stdin);
	freopen("railway.out","w",stdout);
	c=read();s=read();R=read();
	for (int i=1;i<=R;i++) 
	  {
		 o=read();d=read();n=read();
		 maxx=qmax(1,1,c-1,o,d-1); 
		 if (s-maxx<n) printf("NO\n");
		 else {printf("YES\n"); add(1,1,c-1,o,d-1,n); }
	  }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值