用线段树维护区间最大,用map搞一搞判断,和离散化差不多,我语文不好。
#include<iostream>
#include<cstdio>
#include<map>
#include<algorithm>
using namespace std;
map<int,int> mp;
int ni[50005];
struct xds
{
int l,r,sum;
int num,ma;
}tree[200005];
int a[50005];
void up(int dq)
{
tree[dq].sum=tree[dq<<1].sum+tree[dq<<1|1].sum;
tree[dq].ma=max(tree[dq<<1].ma,tree[dq<<1|1].ma);
}
void build(int dq,int l,int r)
{
tree[dq].l=l;
tree[dq].r=r;
if(l==r)
{
tree[dq].sum=1;
tree[dq].ma=a[l];
return ;
}
int mid=(l+r)>>1;
build(dq<<1,l,mid);
build(dq<<1|1,mid+1,r);
up(dq);
}
struct Pair{
int fst,lst;
};
Pair ask(int dq,int l,int r)
{
if(tree[dq].l>=l&&tree[dq].r<=r)
{
Pair ans;
ans.fst=tree[dq].r-tree[dq].l+1;
ans.lst=tree[dq].ma;
return ans;
}
Pair ans;ans.fst=0;ans.lst=0;
int mid=(tree[dq].l+tree[dq].r)>>1;
Pair as;
if(mid>=l)
{
as=ask(dq<<1,l,r);
ans.fst+=as.fst;
ans.lst=max(ans.lst,as.lst);
}
if(mid<r)
{
as=ask(dq<<1|1,l,r);
ans.fst+=as.fst;
ans.lst=max(ans.lst,as.lst);
}
return ans;
}
int n;
int check(int x,int y)
{
int j=upper_bound(ni+1,ni+n+1,x)-ni;
int k=lower_bound(ni+1,ni+n+1,y)-ni;
k--;
Pair ans=ask(1,j,k);
int xx=a[mp[x]];int yy=a[mp[y]];
if(yy&&ans.lst>=yy) return -1;
if(xx&&yy>xx) return -1;
if(xx&&ans.lst>=xx) return -1;
if(!xx||!yy) return 0;
if(ans.fst<y-x-1) return 0;
return 1;
}
int main()
{
scanf("%d",&n);
int x,y;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
mp[x]=i;ni[i]=x;
a[i]=y;
}
build(1,1,n);
int m;
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
int ans=check(x,y);
if(ans==-1)
puts("false");
if(ans==0)
puts("maybe");
if(ans==1)
puts("true");
}
}