这道题看似很复杂,其实就是最基本的分类讨论,再通过线段树维护区间的最大值和最小值。题面->P2471 [SCOI2007] 降雨量。代码写的太丑了将就吧。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=5e4+10;
struct SGT{
int y,v;
}sgt[N];
struct Range{
bool flag;
int val;
}t[N<<2];
int n;
void build(int x,int l,int r){
if(l==r){
t[x]={true,sgt[l].v};
return;
}
int mid=l+r>>1;
build(x<<1,l,mid);build(x<<1|1,mid+1,r);
t[x].val=max(t[x<<1].val,t[x<<1|1].val);
if(sgt[mid+1].y-sgt[mid].y==1&&t[x<<1].flag&&t[x<<1|1].flag)
t[x].flag=true;
else t[x].flag=false;
}
Range query(int u,int l,int r,int x,int y){
if(l>=x&&y>=r){
return t[u];
}
int mid=l+r>>1;
Range res,tmp;
res.flag=true;res.val=INT_MIN;
bool f1=false,f2=false;
if(x<=mid){
f1=true;
tmp=query(u<<1,l,mid,x,y);
res.val=max(tmp.val,res.val);
if(!tmp.flag) res.flag=false;
}
if(y>mid){
f2=true;
tmp=query(u<<1|1,mid+1,r,x,y);
res.val=max(tmp.val,res.val);
if(!tmp.flag) res.flag=false;
}
if(f1&f2)
if(sgt[mid+1].y-sgt[mid].y!=1)
res.flag=false;
return res;
}
inline int upper(int x){//找大的
int l=1,r=n,mid;
int res=INT_MIN;
while(l<=r){
mid=l+r>>1;
if(sgt[mid].y==x)
return mid;
else if(sgt[mid].y>x){
r=mid-1;
res=mid;
}
else l=mid+1;
}
return res;
}
inline int lower(int x){//找小的
int l=1,r=n,mid;
int res=INT_MIN;
while(l<=r){
mid=l+r>>1;
if(sgt[mid].y==x)
return mid;
else if(sgt[mid].y<x){
l=mid+1;
res=mid;
}
else r=mid-1;
}
return res;
}
int main(){
int m;
cin>>n;
for(int i=1;i<=n;i++)
cin>>sgt[i].y>>sgt[i].v;
build(1,1,n);
cin>>m;
while(m--){
int l,r;
cin>>l>>r;
if(r<=l){
cout<<"false"<<"\n";
continue;
}
if(l>=sgt[n].y||r<=sgt[1].y){//范围之外
cout<<"maybe"<<"\n";
continue;
}
int L=upper(l),R=lower(r);
if(sgt[L].y==l&&sgt[R].y==r){//两个都存在
if(sgt[L].v>=sgt[R].v){
if(R-L==1){
if(sgt[R].y-sgt[L].y==1)
cout<<"true"<<"\n";
else cout<<"maybe"<<"\n";
continue;
}
Range res=query(1,1,n,L+1,R-1);
if(res.val>=sgt[R].v){
cout<<"false"<<"\n";
continue;
}
else{
if(res.flag&&l+1==sgt[L+1].y&&r-1==sgt[R-1].y)
cout<<"true"<<"\n";
else cout<<"maybe"<<"\n";
continue;
}
}
else cout<<"false"<<"\n";
}
else if(r==sgt[R].y){//一边存在
if(r-l==1){
cout<<"maybe"<<"\n";
continue;
}
if(R==L){
cout<<"maybe"<<"\n";
continue;
}
int Rr=lower(r-1);
if(Rr<L){
cout<<"maybe"<<"\n";
continue;
}
Range res=query(1,1,n,L,Rr);
if(res.val>=sgt[R].v){
cout<<"false"<<"\n";
continue;
}
cout<<"maybe"<<"\n";
}
else if(l==sgt[L].y){
if(r-l==1){
cout<<"maybe"<<"\n";
continue;
}
int Rr=lower(r-1);
int Ll=upper(l+1);
if(Rr<Ll){
cout<<"maybe"<<"\n";
continue;
}
Range res=query(1,1,n,Ll,Rr);
if(res.val>=sgt[L].v){
cout<<"false"<<"\n";
continue;
}
cout<<"maybe"<<"\n";
}
else
cout<<"maybe"<<"\n";
}
return 0;
}
浙公网安备 33010602011771号