Solution:
本题题目出的是真的好(鬼)。。。~
这两天调得我——快要吐血的万恶之源……
首先我们对于判断时的顺序做一个调整,按情况的可能性从多到少,先判断false,再判断maybe,最后剩下的才是true。
题目中会用到某段区间的最大值进行判断,所以我们可以用一棵线段树去维护(至于区间连续性就没必要用线段树维护了,有更好的方法,亏我开始傻乎乎用线段树去写~
)。
因为读入时的年份是保证递增的,所以对于每次询问x,y(当x\geq y直接输false),我们可以先二分找出第一个不小于x的位置,和y的位置,不妨假设为st和ed,然后判断边界的年份是否相等,并查询出st+1到ed-1的最大值(因为要取出中间一段的最大值,用其和两端比较,注意判断左端点年份不确定时要查询st到ed-1的最大值)。
判断时:
先判false:
1、当右端点年份确定,且中间年份最大降雨量大于等于右端点降雨量
2、当左端点年份确定,且中间年份最大降雨量大于等于左端点降雨量
3、当左右端点年份都确定,且左端点降雨量小于等于右端点降雨量
再判maybe:
1、当左右端点之差不等于左右端点年份之差(等价于年份不连续,也就是我前面所说的更好的判断区间连续的方法)
2、左端点年份不确定
3、右端点年份不确定
(因为已经切掉false的情况了,那么剩下的情况中可以直接照上面的判断!)
最后判断true:
\;\;$若上面情况都不满足,那么肯定是$true
$\quad\;\;$欢迎来踩博客:[five20](https://www.cnblogs.com/five20/p/9123773.html)(蒟蒻写题解不易,转载请注明出处,万分感谢!)
### 代码:
```cpp
#include<bits/stdc++.h>
#define il inline
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define Max(a,b) ((a)>(b)?(a):(b))
using namespace std;
const int N=200005;
int n,m,num[N],ls[N],rs[N];
int ye[N],co[N];
bool f[N];
struct node{
int ans,f;
};
il int gi(){
int a=0;char x=getchar();bool f=0;
while((x<'0'||x>'9')&&x!='-')x=getchar();
if(x=='-')x=getchar(),f=1;
while(x>='0'&&x<='9')a=(a<<3)+(a<<1)+x-48,x=getchar();
return f?-a:a;
}
il void pushup(int rt){
if(rs[rt<<1]==ls[rt<<1|1]-1)f[rt]=f[rt<<1]&f[rt<<1|1];
rs[rt]=rs[rt<<1|1];ls[rt]=ls[rt<<1];
num[rt]=Max(num[rt<<1],num[rt<<1|1]);
}
il void build(int l,int r,int rt){
if(l==r){rs[rt]=ls[rt]=ye[l],num[rt]=co[l],f[rt]=1;return;}
int m=l+r>>1;
build(lson),build(rson);
pushup(rt);
}
il node query(int L,int R,int l,int r,int rt){
if(L<=l&&R>=r){
node tmp;
tmp.ans=num[rt],tmp.f=f[rt];
return tmp;
}
int m=l+r>>1;
node tmp;
tmp.ans=0,tmp.f=1;
if(L<=m){
node x=query(L,R,lson);
tmp.ans=Max(tmp.ans,x.ans);
tmp.f&=x.f;
}
if(R>m){
node x=query(L,R,rson);
tmp.ans=Max(tmp.ans,x.ans);
tmp.f&=x.f;
}
return tmp;
}
int main(){
n=gi();
For(i,1,n)ye[i]=gi(),co[i]=gi();
build(1,n,1);
m=gi();
int x,y;
while(m--){
x=gi(),y=gi();
if(x>=y){printf("false\n");continue;}
int st=lower_bound(ye+1,ye+n+1,x)-ye,ed=lower_bound(ye+1,ye+n+1,y)-ye;
bool fl,fr;int op=0;
fl=ye[st]==x,fr=ye[ed]==y;
if(!fl)st--;
if(st+1<=ed-1)op=query(st+1,ed-1,1,n,1).ans;
if((op>=co[ed]&&fr)||(co[st]<co[ed]&&fl&&fr)||(op>=co[st]&&fl))printf("false\n");
else if(ed-st!=ye[ed]-ye[st]||!fr||!fl)printf("maybe\n");
else printf("true\n");
}
return 0;
}
```