[SCOI2007]降雨量

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。

Sample Input

6
2002 4920
2003 5901
2004 2832
2005 3890
2007 5609
2008 3024
5
2002 2005
2003 2005
2002 2007
2003 2007
2005 2008

Sample Output

false
true
false
maybe
false

HINT

100%的数据满足:1<=n<=50000, 1<=m<=10000, -10^9<=yi<=10^9, 1<=ri<=10^9

Source

POJ 2637 WorstWeather Ever

思路

这道题,,,离散化一下年份,每次询问二分一下左右端点,查询最大值用线段树或者st表都行;

然而,判定贼恶心。。。

//我这里x,y的含义互换了,x<y ,l,r是x,y对应的数组坐标,z=max_(l+1,r-1)QUQ

if(x&&z>=x) false;

if(y&&z>=y) false;

if(x&&y),x<y false;

else

if(x&&y&&l-r+1==y-x-1) true;

else maybe;

代码实现

 1 #include<cstdio>
 2 const int maxn=5e4+10;
 3 inline int min_(int x,int y){return x<y?x:y;}
 4 inline int max_(int x,int y){return x>y?x:y;}
 5 int n,m;
 6 int a[maxn],b[maxn];
 7 int t[maxn<<2];
 8 int lower_bound(int k){
 9     int mid,l=1,r=n;
10     while(l<r){
11         mid=l+r>>1;
12         if(a[mid]<k) l=mid+1;
13         else r=mid;
14     }
15     return l;
16 }
17 void build(int k,int l,int r){
18     if(l==r){
19         t[k]=b[l];
20         return;
21     }
22     int mid=l+r>>1,ls=k<<1,rs=ls|1;
23     build(ls,l,mid);
24     build(rs,mid+1,r);
25     t[k]=max_(t[ls],t[rs]);
26 }
27 int search(int k,int l,int r,int al,int ar){
28     if(al>ar) return -1e9;
29     if(l==al&&r==ar) return t[k];
30     int mid=l+r>>1,ls=k<<1,rs=ls|1,ret=-1e9;
31     if(al<=mid) ret=max_(ret,search(ls,l,mid,al,min_(ar,mid)));
32     if(ar>mid) ret=max_(ret,search(rs,mid+1,r,max_(al,mid+1),ar));
33     return ret;
34 }
35 int main(){
36     scanf("%d",&n);
37     a[0]=-1e9-1,a[n+1]=1e9+1;
38     for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);
39     build(1,1,n);
40     int x,y,z,l,r;
41     scanf("%d",&m);
42     for(int i=1;i<=m;i++){
43         scanf("%d%d",&x,&y);
44         l=lower_bound(x);
45         while(a[l]<=x) l++;
46         r=lower_bound(y);
47         while(a[r]>=y) r--;
48         z=search(1,1,n,l,r);
49         if((a[r+1]==y&&z>=b[r+1])||(a[l-1]==x&&z>=b[l-1])||(a[l-1]==x&&a[r+1]==y&&b[l-1]<b[r+1])) puts("false");
50         else{
51             if(r-l+1==y-x-1&&a[l-1]==x&&a[r+1]==y) puts("true");
52             else puts("maybe");
53         }
54     }
55     return 0;
56 }

 

posted @ 2017-12-20 09:08  J_william  阅读(659)  评论(0编辑  收藏  举报