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;
}