1067: [SCOI2007]降雨量 - BZOJ

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

 

 

其实不难,只不过容易漏掉某些情况

用倍增或者线段树求最值

比如说第X年不确定时,第Y年降雨量必须大于中间的降雨量

直接分四种大情况,然后讨论,就很清晰了

1.X,Y都确定

2.X,Y都不确定

3.X确定,Y不确定

4.X不确定,Y确定

  1 const

  2         maxn=50010;

  3 var

  4         f:array[0..maxn,0..20]of longint;

  5         a,b:array[0..maxn]of longint;

  6         n,m:longint;

  7  

  8 function max(x,y:longint):longint;

  9 begin

 10         if x>y then exit(x);

 11         exit(y);

 12 end;

 13  

 14 function findl(x:longint):longint;

 15 var

 16         l,r,mid:longint;

 17 begin

 18         l:=1;

 19         r:=n;

 20         while l<>r do

 21           begin

 22             mid:=(l+r)>>1;

 23             if a[mid]>=x then r:=mid

 24             else l:=mid+1;

 25           end;

 26         exit(l);

 27 end;

 28  

 29 function findr(x:longint):longint;

 30 var

 31         l,r,mid:longint;

 32 begin

 33         l:=1;

 34         r:=n;

 35         while l<>r do

 36           begin

 37             mid:=(l+r+1)>>1;

 38             if a[mid]<=x then l:=mid

 39             else r:=mid-1;

 40           end;

 41         exit(l);

 42 end;

 43  

 44 function ans(l,r:longint):longint;

 45 var

 46         k:longint;

 47 begin

 48         if l>r then exit(0);

 49         k:=0;

 50         while 1<<(k+1)<r-l+1 do

 51           inc(k);

 52         exit(max(f[l,k],f[r-1<<k+1,k]));

 53 end;

 54  

 55 procedure init;

 56 var

 57       i,j,k:longint;

 58 begin

 59         read(n);

 60         for i:=1 to n do

 61           begin

 62             read(a[i],b[i]);

 63             f[i,0]:=b[i];

 64           end;

 65         k:=1;

 66         j:=1;

 67         while k<n do

 68           begin

 69             for i:=1 to n-k do

 70               f[i,j]:=max(f[i,j-1],f[i+k,j-1]);

 71             k:=k<<1;

 72             inc(j);

 73           end;

 74 end;

 75  

 76 procedure work;

 77 var

 78         i,x,y,l,r:longint;

 79 begin

 80         read(m);

 81         for i:=1 to m do

 82           begin

 83             read(x,y);

 84             l:=findl(x);

 85             r:=findr(y);

 86             if a[l]=x then

 87               if a[r]=y then

 88                 begin

 89                   if ans(l+1,r-1)<b[r] then

 90                     if b[l]>=b[r] then

 91                       if r-l=y-x then writeln('true')

 92                       else writeln('maybe')

 93                     else writeln('false')

 94                   else writeln('false');

 95                 end

 96               else

 97                 begin

 98                   if ans(l+1,r)>=b[l] then writeln('false')

 99                   else writeln('maybe');

100                 end

101             else

102               if a[r]=y then

103                 begin

104                   if ans(l,r-1)<b[r] then writeln('maybe')

105                   else writeln('false');

106                 end

107               else writeln('maybe');

108           end;

109 end;

110  

111 begin

112         init;

113         work;

114 end.
View Code

 

你可能感兴趣的:(2007)