BZOJ#1067. [SCOI2007]降雨量

1067. [SCOI2007]降雨量

思路:

只有a[l]>=a[r] && a[x]>a[r] {x,l<x<r}满足为true,使用st表或者线段树维护最大值即可,
其他情况分类讨论

代码:

#include <bits/stdc++.h>
#define int long long
int _ = 0, Case = 1;
using namespace std;
#define all(v) begin(v),end(v)
#define nline '\n'
const int N = 2000100;
int a[N];
int lg[N], maxn[N][20];
void init() {
    for (int i = 2; i < N; i++) {
        lg[i] = lg[i >> 1] + 1;
    }
}
void st_init(int n) {

    for (int i = 1; i <= n; i++)
        maxn[i][0] = a[i];

    for (int i = 1; i <= lg[n]; i++)
        for (int j = 1; j + (1LL << i) - 1 <= n; j++)
            maxn[j][i] = max(maxn[j][i - 1], maxn[j + (1LL << (i - 1))][i - 1]);
}
int query(int l, int r) {
    int len = lg[r - l + 1];
    return max(maxn[l][len], maxn[r - (1LL << len) + 1][len]);
}
int c[N];
vector<int> v;
int find(int x) {
    return lower_bound(all(v), x) - v.begin() + 1;
}
void solve(int Case) {
    int n;
    cin >> n;
    map<int, int> mp;
    for (int i = 1; i <= n; i++) {
        cin >> c[i] >> a[i];
        v.push_back(c[i]);
        mp[c[i]] = a[i];
    }
    init();
    st_init(n);
    int m;
    cin >> m;
    for (int i = 1; i <= m; i++) {
        int l, r;
        cin >> l >> r;
        int tl = find(l);
        int tr = find(r);
        if (!mp.count(l) and !mp.count(r)) cout << "maybe" << nline;
        else if (mp.count(l) and !mp.count(r)) {
            tl++;
            tr--;
            if (tl > tr) cout << "maybe" << nline;
            else if (query(tl, tr) < mp[l]) cout << "maybe" << nline;
            else cout << "false" << nline;
        } else if (!mp.count(l) and mp.count(r)) {
            tr--;
            if (tl > tr) cout << "maybe" << nline;
            else if (query(tl, tr) < mp[r]) cout << "maybe" << nline;
            else cout << "false" << nline;
        } else {
            if (r - l == tr - tl) {
                tl++, tr--;
                if (mp[r] <= mp[l] and tl > tr) cout << "true" << nline;
                else if (mp[r] <= mp[l] and query(tl, tr) < mp[r]) cout << "true" << nline;
                else cout << "false" << nline;
            } else {
                tl++, tr--;
                if (tl > tr and mp[r] <= mp[l]) cout << "maybe" << nline;
                else if (mp[r] <= mp[l] and query(tl, tr) < mp[r]) cout << "maybe" << nline;
                else cout << "false" << nline;

            }
        }

    }
}

signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
//   for (cin>>_, Case = 1; Case <= _; Case++)
    solve(Case);

    return 0;
}
posted @ 2022-06-24 16:10  指引盗寇入太行  阅读(13)  评论(0编辑  收藏  举报