1067: [SCOI2007]降雨量
Description
我们常常会说这样的话:“X年是自Y年以来降雨量最多的”。它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年。例如2002,2003,2004和2005年的降雨量分别为4920,5901,2832和3890,则可以说“2005年是自2003年以来最多的”,但不能说“2005年是自2002年以来最多的”由于有些年份的降雨量未知,有的说法是可能正确也可以不正确的。
Input
输入仅一行包含一个正整数n,为已知的数据。以下n行每行两个整数yi和ri,为年份和降雨量,按照年份从小到大排列,即yi<yi+1。下一行包含一个正整数m,为询问的次数。以下m行每行包含两个数Y和X,即询问“X年是自Y年以来降雨量最多的。”这句话是必真、必假还是“有可能”
Output
对于每一个询问,输出true,false或者maybe。
Sample Input
6
2002 4920
2003 5901
2004 2832
2005 3890
2007 5609
2008 3024
5
2002 2005
2003 2005
2002 2007
2003 2007
2005 2008
Sample Output
false
true
false
maybe
false
HINT
100%的数据满足:1<=n<=50000, 1<=m<=10000, 10^9<=yi<=10^9, 1<=ri<=10^9
这题一看就要维护区间最值。因为没有修改操作,所以就用RMQ,另外的话就是要离散。接下去就是要认真审题了。。。。。。。。。
“X年是自Y年以来降雨量最多的。”到底什么意思呢。。
它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X以及Y年。
那么再注意一下有些不知道降雨量的年份的处理,这题就过了。
附代码:
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <algorithm>
#define N 50005
using namespace std;
int f[N * 2][30], c[N];
int n, q, x, y, nx, ny;
struct cpp {
int year, num;
inline bool operator <(const cpp &a) const {
return year < a.year;
}
inline bool operator <=(const cpp &a) const {
return num <= a.num;
}
cpp(void) {}
cpp(int y, int n):year(y), num(n) {}
}a[N];
inline int find(int x) {
int l = 1, r = n, mid;
while (l < r) {
mid = (l + r) >> 1;
if (x > a[mid].year) l = mid + 1;
else r = mid;
}
return r;
}
inline int query(int l, int r) { // [l, r]
int len = (r - l + 1), i, Max;
for(i = 1; (Max = (1 << (i - 1))) <= len; i++);
i--; Max >>= 1;
return max(f[l][i], f[r - Max + 1][i]);
}
int main(void) {
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d%d", &a[i].year, &a[i].num);
memset(f, 0, sizeof(f));
for (int i = 1; i <= n; i++) f[i][1] = a[i].num;
for (int j = 2; (x = (1 << (j - 1))) <= n; j++)
for (int i = 1; i <= n; i++) {
f[i][j] = max(f[i][j - 1], f[i + (x >> 1)][j - 1]);
}//RMQ是自己乱打的一点都不高贵...
scanf("%d", &q);
for (int i = 0; i < q; i++) {
scanf("%d%d", &x, &y);
if (i == 32) {
x = x;
}
nx = lower_bound(a + 1, a + n + 1, cpp(x, 0)) - a;
ny = lower_bound(a + 1, a + n + 1, cpp(y, 0)) - a;
if (a[ny].year > y) ny--;
if (a[nx].year == x && a[ny].year == y) {
int p = query(nx + 1, ny - 1);
if (nx - ny == x - y) {
if (a[ny] <= a[nx] && p < a[ny].num) {puts("true"); continue;}
else {puts("false"); continue;}
} else {
if (a[ny] <= a[nx] && p < a[ny].num) {puts("maybe"); continue;}
else {puts("false"); continue;}
}
} else if (a[nx].year == x && a[ny].year != y) {
int p = query(nx + 1, ny);
if (a[nx].num > p) {puts("maybe"); continue;}
else {puts("false"); continue;}
}
else if (a[nx].year != x && a[ny].year == y) {
int p = query(nx, ny - 1);
if (p < a[ny].num) {puts("maybe"); continue;}
else {puts("false"); continue;}
} else {
puts("maybe"); continue;
}
}
return 0;
}