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

题目就是要求实现两种操作,1、求一段区间的最大值/最小值;2、给一段区间上的每一个数加上一个值。
对于区间,理应想到线段树。而线段树是十分灵活的,几乎每道题目都不一样,其中关于要在结点中保存哪些信息的问题就值得思考。
要快速地查询区间最值,首先考虑用seg[i].max表示该区间内的最大值,这样一来,执行“给[a,b]区间每个数增加d”的时候,只需要递归到一个完整的被覆盖着的区间,将这个区间的max增加d即可,回溯时更新父结点。但是这么做是有问题的,某个被覆盖过的区间以上的区间信息确实没有问题,但是它以下呢?max值是不能够向下传递的!所以需要增加区间信息。
给出如下结果:
1、seg[i].max表示结点i表示的区间的最大值;
2、seg[i].cover表示结点i表示的区间被某个售票申请直接覆盖的数量
这样一来,需要统计某个已经被覆盖的区间的子结点的信息时,将cover所包含的信息向下传递即可。因为cover是可以向下传递的:一个区间的值全部增加d,它的子结点的值也必然全部增加d。
以下是我的代码:
#include<stdio.h>
#define maxn 60007
#define L(x) (x<<1)
#define R(x) ((x<<1)+1)
#define max(a,b) (a>b?a:b)
struct
{
    
long a,b;
    
long max,cover;
}seg[maxn
*3];
long n,s,m;
void build(long node,long x,long y)
{
    
long mid=(x+y)>>1;
    seg[node].a
=x;seg[node].b=y;
    seg[node].max
=seg[node].cover=0;
    
if(x<y)
    {
       build(L(node),x,mid);
       build(R(node),mid
+1,y);
    }
}
bool ok(long node,long x,long y,long d)
{
    
long a=seg[node].a,b=seg[node].b,mid=(a+b)>>1;
    
bool re=false,cal=false;
    
if(x<=a&&b<=y)
      
return (seg[node].max+d<=s);
    
if(seg[node].cover>0)
    {
       seg[L(node)].cover
+=seg[node].cover;
       seg[R(node)].cover
+=seg[node].cover;
       seg[L(node)].max
+=seg[node].cover;
       seg[R(node)].max
+=seg[node].cover;
       seg[node].cover
=0;
       seg[node].max
=max(seg[L(node)].max,seg[R(node)].max);
    }
    
if(mid>=x)
    {
       re
=ok(L(node),x,y,d);
       cal
=true;
    }
    
if(mid+1<=y)
      re
=((re||!cal)&&ok(R(node),x,y,d));
    
return re;
}
void insert(long node,long x,long y,long d)
{
    
long a=seg[node].a,b=seg[node].b,mid=(a+b)>>1;
    
if(x<=a&&b<=y)
    {
       seg[node].max
+=d;
       seg[node].cover
+=d;
    }
    
else
    {
       
if(mid>=x)
       {
          insert(L(node),x,y,d);
          seg[node].max
=max(seg[node].max,seg[L(node)].max);
       }
       
if(mid+1<=y)
       {
          insert(R(node),x,y,d);
          seg[node].max
=max(seg[node].max,seg[R(node)].max);
       }
    }
}
int main()
{
    freopen(
"railway.in","r",stdin);
    freopen(
"railway.out","w",stdout);
    scanf(
"%ld%ld%ld",&n,&s,&m);
    build(
1,1,n-1);
    
while(m--)
    {
       
long a,b,d;
       scanf(
"%ld%ld%ld",&a,&b,&d);
       
if(ok(1,a,b-1,d))
       {
          printf(
"YES\n");
          insert(
1,a,b-1,d);
       }
       
else printf("NO\n");
    }
return 0;
}


posted on 2010-02-24 08:38 lee1r 阅读(870) 评论(0)  编辑 收藏 引用 所属分类: 题目分类:数据结构

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理