扩大
缩小

【题解】[SCOI2007]降雨量

原题链接

这题调了我快一个小时,在此记录下这题的坑点。

备注:$A$ 无数据指的是 $A$ 年份没有雨量记录;$A \sim B$ 指 $A$ 年到 $B$ 年间(包括 $A,B$)的所有年份。

  • $X,Y$ 都无数据的情况下,答案必为 maybe
  • $X$ 无数据的情况下,需要判断 $Y+1 \sim X$ 中有数据的年份是否大于等于 $Y$ 年的雨量,是输出 false,不是输出 maybe
  • $Y$ 无数据的情况下
    • 若 $X$ 比所有年份都早,则数据全无,直接输出 maybe
    • 否则判断 $Y \sim X-1$ 中有数据的年份是否大于等于 $X$ 年的雨量,是输出 false,不是输出 maybe
  • 其余情况
    • 判断 $Y+1 \sim X$ 中有数据的年份是否不等于 $Y$ 年的雨量,是输出 false
    • 判断 $Y+1 \sim X-1$ 中有数据的年份是否等于 $X$ 年的雨量,是输出 false
    • 判断 $X$ 年的雨量是否大于 $Y$ 年的雨量,是输出 false
    • 判断 $X \sim Y$ 间是否每年都记录了数据,是输出 true,否则 maybe

其它没什么好说的,线段树维护最值,map 或离散化解决年份值域问题。

代码如下:

#include <algorithm>
#include <cstdio>
#include <map>
#define INF 1e9
#define eps 1e-6
typedef long long ll;
using namespace std;

map <int, int> m;
int n, q, y[50010], R[50010], maxx[200010];

inline int max(int a, int b){
    return a > b ? a : b;
}

void build(int i, int l, int r){
    if(l == r){
        maxx[i] = R[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(i << 1, l, mid);
    build(i << 1 | 1, mid + 1, r);
    maxx[i] = max(maxx[i << 1], maxx[i << 1 | 1]);
}

int query(int i, int l, int r, int x, int y){
    if(l > r) return 0;
    if(l >= x && r <= y) return maxx[i];
    int ss = 0, mid = (l + r) >> 1;
    if(x <= mid) ss = max(ss, query(i << 1, l, mid, x, y));
    if(y > mid) ss = max(ss, query(i << 1 | 1, mid + 1, r, x, y));
    return ss;
}

int main(){

    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
        scanf("%d%d", &y[i], &R[i]), m[y[i]] = i;
    build(1, 1, n);
    scanf("%d", &q);
    for(int i = 1, X, Y, pos, poss; i <= q; i++){
        scanf("%d%d", &X, &Y);
        pos = lower_bound(y + 1, y + n + 1, X) - y;
        if(!m[X] && !m[Y]) puts("maybe");
        else if(!m[Y]){
            poss = lower_bound(y + 1, y + n + 1, Y) - y - 1;
            if(query(1, 1, n, pos + 1, poss) >= R[m[X]]) puts("false");
            else puts("maybe");
        }
        else if(!m[X]){
            if(m[Y] == 1) puts("maybe");
            else if(query(1, 1, n, pos, m[Y] - 1) >= R[m[Y]]) puts("false");
            else puts("maybe");
        }
        else{
            if(query(1, 1, n, pos + 1, m[Y]) != R[m[Y]]) puts("false");
            else if(query(1, 1, n, pos + 1, m[Y] - 1) == R[m[Y]]) puts("false");
            else if(query(1, 1, n, pos + 1, m[Y] - 1) >= R[m[X]]) puts("false");
            else if(R[m[Y]] > R[m[X]]) puts("false");
            else if(Y - X != m[Y] - m[X]) puts("maybe");
            else puts("true");
        }
    }

    return 0;
}
posted @ 2021-05-24 22:48  HoshizoraZ  阅读(106)  评论(0)    收藏  举报