码迷,mamicode.com
首页 > 其他好文 > 详细

CSUOJ1238--兵临城下

时间:2015-05-16 18:26:18      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:线段树

这个题目的难点在于p操作时快速确定没预热炮中的最小编号.我是用线段树为每门炮维护了一个最后可开炮时间,然后每次需要预热一门炮时就用二分加线段树查询满足要求的最小编号.要注意如果一门炮可以开炮时间的结尾恰好是我们查询的时间,我们也要将其看成不可以开炮需要重新预热的(我就在这WA了好几发).

代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;

int const maxn=31000;
long long Min[maxn*4],Max[maxn*4];

void Build(int rt,int l,int r)
{
       if(l>=r)
       {
            Min[rt]=0;
            return ;
       }
       int m=(l+r)/2;
       Build(rt*2,l,m);
       Build(rt*2+1,m+1,r);
       Min[rt]=min(Min[2*rt],Min[2*rt+1]);
}

void update(int rt,int l,int r,int x,int num)
{
        if(l>=r)
        {
               Min[rt]=num;
               return ;
        }
        int m=(l+r)/2;
        if(m>=x)
           update(rt*2,l,m,x,num);
        if(m<x)
           update(rt*2+1,m+1,r,x,num);
        Min[rt]=min(Min[rt*2],Min[2*rt+1]);
}

long long query(int rt,int l,int r,int ql,int qr)
{
        long long ans=0x7fffffff;
        if(ql<=l&&qr>=r)
        {
             return Min[rt];
        }
        int m=(l+r)/2;
       if(m>=ql)
           ans=min(ans,query(rt*2,l,m,ql,qr));
       if(m<qr)
           ans=min(ans,query(rt*2+1,m+1,r,ql,qr));
       return ans;
}

int main()
{
      //freopen("test0.in","r",stdin);
      //freopen("out.txt","w",stdout);
       int n,t,p;
       while(scanf("%d%d%d",&n,&t,&p)!=EOF)
       {
               memset(Min,0,sizeof(Min));
               while(p--)
               {
                     int x,y;
                     char str[10];
                     scanf("%d%s",&x,str);
                     if(str[0]==‘p‘)
                     {
                            int l=1,r=n;
                            int tmp;
                            while(l<=r)
                            {
                                  int m=(l+r)/2;
                                  if(query(1,1,n,l,m)<=x)
                                      r=m-1,tmp=m;
                                  else
                                      l=m+1;
                            }
                            update(1,1,n,tmp,x+t*60);
                            printf("%d\n",tmp);
                     }
                     else
                     {
                            scanf("%d",&y);
                            int k=query(1,1,n,y,y);
                            //cout<<k<<endl;
                            if(k<=x)
                                 printf("Cannot\n");
                            else
                            {
                                  printf("Fire!\n");
                                  update(1,1,n,y,x+t*60);
                            }
                     }
               }
       }
   return 0;
}

CSUOJ1238--兵临城下

标签:线段树

原文地址:http://blog.csdn.net/acm_lkl/article/details/45769541

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!