ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

Description

  我们常常会说这样的话:“X年是自Y年以来降雨量最多的”。它的含义是X年的降雨量不超过Y年,且对于任意 Y<Z<X,Z年的降雨量严格小于X年。例如2002,2003,2004和2005年的降雨量分别为4920,5901,2832和3890, 则可以说“2005年是自2003年以来最多的”,但不能说“2005年是自2002年以来最多的”由于有些年份的降雨量未 知,有的说法是可能正确也可以不正确的。

Input

  输入仅一行包含一个正整数n,为已知的数据。以下n行每行两个整数yi和ri,为年份和降雨量,按照年份从小 到大排列,即yi<yi+1。下一行包含一个正整数m,为询问的次数。以下m行每行包含两个数Y和X,即询问“X年是 自Y年以来降雨量最多的。”这句话是必真、必假还是“有可能”。

Output

  对于每一个询问,输出true,false或者maybe。

用zkw线段树维护区间最大值,二分确定询问对应的区间

#include<cstdio>
#include<algorithm>
inline int input(){
    int x=0,c=getchar(),f=1;
    while(c>57||c<48){if(c=='-')f=-1;c=getchar();}
    while(c>47&&c<58)x=x*10+c-48,c=getchar();
    return x*f;
}
const int inf=2147483647;
int n,m,M=65536;
int x[50005],y[50005],mx[131072];
inline int max(int a,int b){return a>b?a:b;}
inline int find(int l,int r){
    int Mx=-inf;
    if(l<=r)
    for(l+=M+1,r+=M+3;l^r^1;l>>=1,r>>=1){
        if(~l&1)Mx=max(Mx,mx[l^1]);
        if(r&1)Mx=max(Mx,mx[r^1]);
    }
    return Mx;
}
int main(){
    n=input();
    while(n*2+10<M/2)M/=2;
    for(int i=0;i<n;i++){
        x[i]=input();
        y[i]=input();
    }
    x[n]=inf;
    for(int i=0;i<n;i++){
        int w=i+M+2;
        mx[w]=y[i];
    }
    for(int i=M-1;i;i--){
        int l=i<<1,r=l^1;
        mx[i]=max(mx[l],mx[r]);
    }
    m=input();
    while(m--){
        int a=input(),b=input();
        int l=std::lower_bound(x,x+n,a)-x;
        int r=std::upper_bound(x,x+n,b)-x-1;
        if(a>b)puts("false");
        else if(l>r)puts("maybe");
        else{
            bool lk=x[l]==a,rk=x[r]==b;
            int Mx=find(l+lk,r-rk);
            if(lk&&Mx>=y[l]||rk&&Mx>=y[r]||lk&&rk&&y[l]<y[r])puts("false");
            else if(r-l==b-a&&lk&&rk&&y[l]>=y[r])puts("true");
            else puts("maybe");
        }
    }
    return 0;
}

 

 

posted on 2016-05-07 14:48  nul  阅读(400)  评论(0编辑  收藏  举报