P2471 [SCOI2007] 降雨量 题解
分析
分讨题。
首先发现是 RMQ 问题(区间最值),可以用线段树或 ST 表来维护(代码为线段树 ,因为我忘记 ST 表怎么写了)。
然后发现有些年份不明确导致区间判断似乎不好搞。
但事实上只要判断下标差是否等于年份差即可得出该区间有无不明确年份。
其次考虑“必真”,“必假”,“有可能”三种结果的优先级。
稍微想想就会发现 \(\text{False} \gt \text{Maybe} \gt \text{True}\)。
于是先考虑 \(\text{False}\)。
- 如果 \(X\) 明确,且 \(Y + 1 \sim X - 1\) 区间内存在 \(Z, r_Z \ge r_X\)。
- 如果 \(Y\) 明确,且 \(Y + 1 \sim X - 1\) 区间内存在 \(Z, r_Z \ge r_Y\)。
- 如果 \(X, Y\) 明确,且 \(r_X \gt r_Y\)。
然后考虑 \(\text{Maybe}\)(此时必然不满足上述条件)。
-
如果 \(X, Y\) 明确,且 \(Y + 1 \sim X - 1\) 区间内存在 \(Z\) 不明确。
-
如果 \(X\) 不明确。
-
如果 \(Y\) 不明确。
以上条件不满足的自然是 \(\text{True}\) 了。
点击查看代码
/*
--------------------------------
| code by FRZ_29 |
| code time |
| 2024/09/09 |
| 12:15:58 |
| 星期一 |
--------------------------------
*/
#include <iostream>
#include <climits>
#include <cstdio>
#include <ctime>
using namespace std;
void RD() {}
template<typename T, typename... U> void RD(T &x, U&... arg) {
x = 0; int f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
x *= f; RD(arg...);
}
const int N = 5e4 + 5;
#define LS (rt << 1)
#define RS (rt << 1 | 1)
#define MID (l + r >> 1)
#define PRINT(x) cout << #x << " = " << x << "\n"
#define LF(i, __l, __r) for (int i = __l; i <= __r; i++)
#define RF(i, __r, __l) for (int i = __r; i >= __l; i--)
int n, y[N], _r[N], Max[N << 2], m;
void up(int rt) {
Max[rt] = max(Max[LS], Max[RS]);
}
void build(int rt, int l, int r) {
if (l == r) {
Max[rt] = _r[l];
return;
}
build(LS, l, MID), build(RS, MID + 1, r);
up(rt);
}
int query(int rt, int l, int r, int L, int R) {
if (L <= l && r <= R) return Max[rt];
int ans = 0;
if (MID >= L) ans = max(ans, query(LS, l, MID, L, R));
if (MID < R) ans = max(ans, query(RS, MID + 1, r, L, R));
return ans;
}
int main() {
freopen("read.in", "r", stdin);
freopen("out.out", "w", stdout);
// time_t st = clock();
RD(n);
LF(i, 1, n) RD(y[i], _r[i]);
build(1, 1, n);
RD(m);
while (m--) {
int X, Y, ans = 0; RD(X, Y);
int st = lower_bound(y + 1, y + n + 1, X) - y,
ed = lower_bound(y + 1, y + n + 1, Y) - y;
bool is_st = y[st] == X, is_ed = y[ed] == Y;
if (!is_st) st--;
if (st + 1 <= ed - 1) ans = query(1, 1, n, st + 1, ed - 1);
if ((ans >= _r[ed] && is_ed) || (ans >= _r[st] && is_st) || (_r[st] < _r[ed] && is_st && is_ed)) puts("false");
else if ((ed - st != y[ed] - y[st] && is_ed && is_st) || !is_st || !is_ed) puts("maybe");
else puts("true");
}
// printf("\n%dms", clock() - st)
return 0;
}
/* ps:FRZ弱爆了 */