lnk-k

导航

 

这道题看似很复杂,其实就是最基本的分类讨论,再通过线段树维护区间的最大值和最小值。题面->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;
}
posted on 2025-07-29 00:04  1uoan  阅读(8)  评论(0)    收藏  举报