ST 表求助
查看原帖
ST 表求助
124152
AmamiyaYuuko楼主2021/9/5 00:13

思路是先把所有出现过的年份存下来,如果两个年份之间差了不止一年就再加一个年份,降水量设成无穷。

每次查询先查询不考虑无穷的最大值是不是大于右端点,然后再查询考虑无穷的最大值是不是大于右端点。

只有一半的分,看测试点是少判了 false 的情况,求助

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>

template <class T>
inline void read(T &x) {
    x = 0;
    int f = 0;
    char ch = getchar();
    while (!isdigit(ch))    { f |= ch == '-'; ch = getchar(); }
    while (isdigit(ch))     { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar(); }
    x = f ? -x : x;
    return ;
}

typedef unsigned long long uLL;
typedef long long LL;

struct Query {
    int l, r;
} b[10010];

int f[200010][20], g[200010][20];
int y[50010], A[200010], w[200010], v1[200010], v2[200010], lg[200010], r[50010];
int n, m, len, l;

int queryMax1(int l, int r) {
    int x = lg[r - l + 1];
    return std::max(f[l][x], f[r - (1 << x) + 1][x]);
}

int queryMax2(int l, int r) {
    int x = lg[r - l + 1];
    return std::max(g[l][x], g[r - (1 << x) + 1][x]);
} 

int main() {
    read(n);
    for (int i = 2; i <= 200000; ++i)    lg[i] = lg[i >> 1] + 1;
    for (int i = 1; i <= n; ++i)    read(y[i]), read(r[i]), A[++len] = y[i];
    read(m);
    for (int i = 1; i <= m; ++i)    read(b[i].l), read(b[i].r), A[++len] = b[i].l, A[++len] = b[i].r;
    std::sort(A + 1, A + len + 1);
    l = len;
    for (int i = 1; i < l; ++i)    A[++len] = A[i] + 1;
    std::sort(A + 1, A + len + 1);
    len = std::unique(A + 1, A + len + 1) - A - 1;
    for (int i = 1; i <= len; ++i)    v1[i] = 2e9, v2[i] = -2e9;
    for (int i = 1; i <= n; ++i)    y[i] = std::lower_bound(A + 1, A + len + 1, y[i]) - A;
    for (int i = 1; i <= n; ++i)    v1[y[i]] = v2[y[i]] = r[i];
    for (int i = 1; i <= m; ++i)    b[i].l = std::lower_bound(A + 1, A + len + 1, b[i].l) - A, b[i].r = std::lower_bound(A + 1, A + len + 1, b[i].r) - A;
    for (int i = 1; i <= len; ++i)    f[i][0] = v1[i], g[i][0] = v2[i];
    for (int j = 1; j <= 20; ++j) {
        for (int i = 1; i + (1 << j) - 1 <= len; ++i) {
            f[i][j] = std::max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
            g[i][j] = std::max(g[i][j - 1], g[i + (1 << (j - 1))][j - 1]);
        }
    }
    for (int i = 1; i <= m; ++i) {
        if (v1[b[i].r] == 2e9) {
            puts("maybe");
            continue;
        }
        if (b[i].l + 1 == b[i].r) {
            if (v1[b[i].r] == 2e9 || v1[b[i].l] == 2e9) {
                puts("maybe");
            } else if (v1[b[i].r] <= v1[b[i].l]) {
                puts("true");
            } else {
                puts("false");
            }
            continue;
        }
        if (queryMax2(b[i].l + 1, b[i].r - 1) >= v1[b[i].r] || v1[b[i].r] > v1[b[i].l]) {
            puts("false");
            continue;
        }
        if (queryMax1(b[i].l + 1, b[i].r - 1) >= v1[b[i].r]) {
            puts("maybe");
            continue;
        }
        puts("true");
    }
    return 0;
}
2021/9/5 00:13
加载中...