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=,c=getchar(),f=;
while(c>||c<){if(c=='-')f=-;c=getchar();}
while(c>&&c<)x=x*+c-,c=getchar();
return x*f;
}
const int inf=;
int n,m,M=;
int x[],y[],mx[];
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+,r+=M+;l^r^;l>>=,r>>=){
if(~l&)Mx=max(Mx,mx[l^]);
if(r&)Mx=max(Mx,mx[r^]);
}
return Mx;
}
int main(){
n=input();
while(n*+<M/)M/=;
for(int i=;i<n;i++){
x[i]=input();
y[i]=input();
}
x[n]=inf;
for(int i=;i<n;i++){
int w=i+M+;
mx[w]=y[i];
}
for(int i=M-;i;i--){
int l=i<<,r=l^;
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-;
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 ;
}