1004 [SCOI2007]降雨量 st表 lower_bound 模拟

 

分析

找到区间的左端点和右端点,根据区间长短判断中间有没有缺年份

STL :  lower_bound (数组边界,值) - 数组

st表找区间最大值。

反正很难写

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define T puts("true");continue;
#define F puts("false");continue;
#define M puts("maybe");continue;
using namespace std;
const int N=5e4+5;

int f[N][20];
int y[N],yu[N];
int n,m;

void init() {
    for(int i=1;i<=n;i++)f[i][0]=yu[i];
    for(int j=1;(1<<j)<=n;j++)
        for(int i=1;i+(1<<j)-1<=n;i++)
            f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}

int query(int l,int r) {
    int len=r-l+1;
    int k=log(len)/log(2);
    return max(f[l][k],f[r-(1<<k)+1][k]);
}

signed main() {
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>y[i]>>yu[i];
    init();
    cin>>m;
    while(m--) {
        int l,r;cin>>l>>r;
        int p1=lower_bound(y+1,y+1+n,l)-y;
        int p2=lower_bound(y+1,y+1+n,r)-y;//离散化处理
        bool f1=((p1==n+1)||(y[p1]!=l))?0:1;//判断是否有这个年份
        bool f2=((p2==n+1)||(y[p2]!=r))?0:1;
        if(f1==0&&f2==0){M};//都不存在,那就是可能
        if(f1!=0&&f2!=0) {//都存在
            if(yu[p2]>yu[p1]){F}//后面大于前面
            if(l+1==r){T}//中间没有其他年份
            if(p1+1==p2){M}//中间有其他年份,但都未知
            if(query(p1+1,p2-1)>=yu[p2]){F}//中间有其他年份,且比r大
            if(p2-p1==r-l){T}//中间连续
            {M}
        }
        if(f1!=0&&f2==0) {//只有第一个有
            if(p1+1==p2){M}//中间没有其他的值
            if(query(p1+1,p2-1)>=yu[p1]){F}//中间的l大,那就一定不满足比r小
            {M}
        }
        if(f1==0&&f2!=0) {//只有第二个有
            if(p1==p2){M}
            if(query(p1,p2-1)>=yu[p2]){F}//对中间的值进行判断
            {M}
        }
    }
    return 0;
}

 

posted @ 2022-08-09 02:54  er007  阅读(29)  评论(0)    收藏  举报