[SCOI2007]降雨量

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

Solution

考虑问题的主要限制,l>=r>(l到r的所有数)。

首先,如果l=r,那么肯定是合法的。

然后直接判如果l<r,干掉。

再判l+1=r.如果l和r都已知,那么就true,否则maybe。

再判一下l到r之间有没有数,如果没有,就maybe。

如果没有r的情况得特判一下,l和r之间最大值大于l(这个很重要),干掉,否则maybe。

然后再判中间的数和r的关系,和l是否有值,还有区间长度。

真**恶心。

Code

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#define N 50002
#define mm make_pair
using namespace std;
int p[N][20],n,num1,num2,num3,iid,id[N],q,iiid;
inline int calc(int l,int r){
    int lo=log(r-l+1)/log(2);
    return max(p[l][lo],p[r-(1<<lo)+1][lo]); 
} 
int main(){
    scanf("%d",&n);int x,y;
    for(int i=1;i<=n;++i)scanf("%d%d",&id[i],&p[i][0]);
    for(int i=1;(1<<i)<=n;++i)
        for(int j=1;j+(1<<i)-1<=n;++j)
          p[j][i]=max(p[j][i-1],p[j+(1<<i-1)][i-1]);
    scanf("%d",&q);
    while(q--){
        scanf("%d%d",&x,&y);
        if(x==y){
            printf("true\n");
            continue;
        }
        num1=upper_bound(id+1,id+n+1,x)-id;
        num2=lower_bound(id+1,id+n+1,y)-id-1;
        iid=num2+1;iiid=num1-1;
        if(id[iid]==y&&id[iiid]==x&&p[iid][0]>p[iiid][0]){
            printf("false\n");
            continue;
        }
        if(x+1==y){
            if(id[iid]==y&&id[iiid]==x)
            printf("true\n");
            else printf("maybe\n");
            continue;
        }
        if(num1>num2){ 
            printf("maybe\n");
            continue;
        }
        if(id[iid]!=y){
        if(id[iiid]!=x){
            printf("maybe\n");
            continue;
        }
        num3=calc(num1,num2);
        if(num3>=p[iiid][0]){
            printf("false\n");
            continue;
        }
        printf("maybe\n");
        continue;
        }
        num3=calc(num1,num2);
        if(num3>=p[iid][0]){
            printf("false\n");
            continue;
        }
        if(id[iiid]!=x){
            printf("maybe\n");
            continue;
        }
        if(num2-num1!=(y-1)-(x+1))printf("maybe\n");
        else printf("true\n");
    }
    return 0;
}
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#define N 50002
#define mm make_pair
using namespace std;
int p[N][20],n,num1,num2,num3,iid,id[N],q,iiid;
inline int calc(int l,int r){
    int lo=log(r-l+1)/log(2);
    return max(p[l][lo],p[r-(1<<lo)+1][lo]); 
} 
int main(){
    scanf("%d",&n);int x,y;
    for(int i=1;i<=n;++i)scanf("%d%d",&id[i],&p[i][0]);
    for(int i=1;(1<<i)<=n;++i)
        for(int j=1;j+(1<<i)-1<=n;++j)
          p[j][i]=max(p[j][i-1],p[j+(1<<i-1)][i-1]);
    scanf("%d",&q);
    while(q--){
        scanf("%d%d",&x,&y);
        if(x==y){
            printf("true\n");
            continue;
        }
        num1=upper_bound(id+1,id+n+1,x)-id;
        num2=lower_bound(id+1,id+n+1,y)-id-1;
        iid=num2+1;iiid=num1-1;
        if(id[iid]==y&&id[iiid]==x&&p[iid][0]>p[iiid][0]){
            printf("false\n");
            continue;
        }
        if(x+1==y){
            if(id[iid]==y&&id[iiid]==x)
            printf("true\n");
            else printf("maybe\n");
            continue;
        }
        if(num1>num2){ 
            printf("maybe\n");
            continue;
        }
        if(id[iid]!=y){
        if(id[iiid]!=x){
            printf("maybe\n");
            continue;
        }
        num3=calc(num1,num2);
        if(num3>=p[iiid][0]){
            printf("false\n");
            continue;
        }
        printf("maybe\n");
        continue;
        }
        num3=calc(num1,num2);
        if(num3>=p[iid][0]){
            printf("false\n");
            continue;
        }
        if(id[iiid]!=x){
            printf("maybe\n");
            continue;
        }
        if(num2-num1!=(y-1)-(x+1))printf("maybe\n");
        else printf("true\n");
    }
    return 0;
}

 

posted @ 2018-10-28 21:45  comld  阅读(181)  评论(0编辑  收藏  举报