思路:用线段树来查询年份之间降雨量的最大值,用二分查找来找到年份下标。
然后进行分类讨论处理即可。(分类讨论详见代码)
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl '\n'
#define pii pair<int,int>
const int N=5e4+5;
int n,m,minn=1e18;
int a[N],b[N],tree[N*4];
void build(int l,int r,int rt){//建树
if(l==r){
tree[rt]=b[l];
return ;
}
int mid=(l+r)/2;
build(l,mid,rt*2);
build(mid+1,r,rt*2+1);
tree[rt]=max(tree[rt*2],tree[rt*2+1]);
}
int query(int L,int R,int l,int r,int rt){//区间查询 (查询区间最大值)
if(L<=l && r<=R) return tree[rt];
int mid=(l+r)/2,ans=0;
if(L<=mid) ans=max(ans,query(L,R,l,mid,rt*2));
if(R>mid) ans=max(ans,query(L,R,mid+1,r,rt*2+1));
return ans;
}
string solve(int u,int v){
//找到首尾两个年份对应的下标
int x=lower_bound(a+1,a+n+1,u)-a,y=lower_bound(a+1,a+n+1,v)-a;
if(u!=a[x]){//当首年份没有确定的降雨量时
//当尾年份也没有确定的降雨量时,尾年份的降雨量有可能是最大值
//当尾年份的下标是 1 时,首尾年份之间的降雨量都是未知的,所以尾年份的降雨量有可能是最大值
if(v!=a[y] || y==1) return "maybe";
//当首年份小于已知降雨量的最小年份时
if(u<minn){
//当首尾年份区间内的最大降雨量不小于尾年份的降雨量时,尾年份的降雨量一定不是最大值
//反之,有可能是最大值
//(下面的 “同上 ”即以上这两条件)
if(query(1,y-1,1,n,1)>=b[y]) return "false";
return "maybe";
}else{
//同上
if(query(x,y-1,1,n,1)>=b[y]) return "false";
return "maybe";
}
}
if(v!=a[y]){//当尾年份没有确定的降雨量时
//当首年份的下标是 n 时,首尾年份之间的降雨量都是未知的,所以尾年份的降雨量有可能是最大值
if(x==n) return "maybe";
//尾年份的降雨量最多与首年份的降雨量相等
//此时,当首尾年份区间内的最大降雨量不小于首年份的降雨量时,尾年份的降雨量一定不是最大值
//反之,有可能是最大值
if(query(x+1,y-1,1,n,1)>=b[x]) return "false";
return "maybe";
}
//当首尾年份都有确定的降雨量时
//当尾年份的降雨量大于首年份的降雨量时不满足条件,返回 "false"
//同上
if(b[x]<b[y] || query(x+1,y-1,1,n,1)>=b[y]) return "false";
//如果首尾年份区间内还有未知的年份降雨量信息,那么尾年份的降雨量有可能是最大值
//反之,尾年份的降雨量一定是最大值
if(y-x!=v-u) return "maybe";
return "true";
}
signed main(){
IOS
cin >> n;
for(int i=1;i<=n;i++){
cin >> a[i] >> b[i];
minn=min(minn,a[i]);//minn记录年份最小值
}
build(1,n,1);//建树
cin >> m;
while(m--){
int u,v;
cin >> u >> v;
cout << solve(u,v) << endl;
}
return 0;
}