降雨量 BZOJ 1067
降雨量
【问题描述】
我们常常会说这样的话:“X年是自Y年以来降雨量最多的”。它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年。例如2002,2003,2004和2005年的降雨量分别为4920,5901,2832和3890,则可以说“2005年是自2003年以来最多的”,但不能说“2005年是自2002年以来最多的”由于有些年份的降雨量未知,有的说法是可能正确也可以不正确的。
【输入格式】
输入仅一行包含一个正整数n,为已知的数据。以下n行每行两个整数yi和ri,为年份和降雨量,按照年份从小到大排列,即yi<yi+1。下一行包含一个正整数m,为询问的次数。以下m行每行包含两个数Y和X,即询问“X年是自Y年以来降雨量最多的。”这句话是必真、必假还是“有可能”。
【输出格式】
对于每一个询问,输出true,false或者maybe。
【样例输入】
6
2002 4920
2003 5901
2004 2832
2005 3890
2007 5609
2008 3024
5
2002 2005
2003 2005
2002 2007
2003 2007
2005 2008
【样例输出】
false
true
false
maybe
false
【数据范围】
100%的数据满足:1<=n<=50000, 1<=m<=10000, -10^9<=yi<=10^9, 1<=ri<=10^9
题解:
分类大讨论······
将所有必假必真判段出来,剩下的就是有可能的情况啦
题面x、y,输入是y、x,—_—
我们按“X年的降雨量不超过Y年”来说
首先如果x的年份小于y的年份,那么肯定是假的
然后如果存在x年大于y年的降雨量,也是假的
我们用线段树查询x到y的区间最值,即题目中z的最值
如果存在x年或y年的降雨量不大于最值,还是假的
如果x年到y年的降雨量全部已知,同时最值严格小于x年,还不满足前三个条件,这就是真的
不满足前四个条件就是有可能
1 #include<algorithm>
2 #include<iostream>
3 #include<cstring>
4 #include<cstdlib>
5 #include<cstdio>
6 #include<cmath>
7 using namespace std;
8 int n, m, x, y, u, v, a, b, ma, ye[1000001], wa[1000001], mx[1000001];
9 inline int Max(int x, int y)
10 {
11 return (x < y) ? y : x;
12 }
13 void Build(int k, int l, int r)
14 {
15 if(l == r)
16 {
17 mx[k] = wa[l];
18 return;
19 }
20 int mi = l + r >> 1;
21 Build(k << 1, l, mi);
22 Build(k << 1 | 1, mi + 1, r);
23 mx[k] = Max(mx[k << 1], mx[k << 1 | 1]);
24 }
25 int Ask(int k, int l, int r, int x, int y)
26 {
27 if(x <= l && r <= y) return mx[k];
28 int mi = l + r >> 1, cc = -2147483647;
29 if(mi >= x) cc = Max(cc, Ask(k << 1, l, mi, x, y));
30 if(mi < y) cc = Max(cc, Ask(k << 1 | 1, mi + 1, r, x, y));
31 return cc;
32 }
33 int Find(int x)
34 {
35 int l = 1, r = n + 1, wz = 0;
36 while(l <= r)
37 {
38 int mi = l + r >> 1;
39 if(x <= ye[mi]) wz = mi, r = mi - 1;
40 else l = mi + 1;
41 }
42 return wz;
43 }
44 int main()
45 {
46 scanf("%d", &n);
47 for(int i = 1; i <= n; ++i) scanf("%d%d", &ye[i], &wa[i]);
48 ye[n + 1] = 2147483647;
49 Build(1, 1, n);
50 scanf("%d", &m);
51 for(int i = 1; i <= m; ++i)
52 {
53 scanf("%d%d", &x, &y);
54 if(x > y)
55 {
56 printf("false\n");
57 continue;
58 }
59 u = Find(x), v = Find(y);
60 a = (ye[u] == x), b = (ye[v] == y);
61 if(a && b && wa[v] > wa[u])
62 {
63 printf("false\n");
64 continue;
65 }
66 u -= (!a);
67 if(u + 1 > v - 1) ma = -2147483647;
68 else ma = Ask(1, 1, n, u + 1, v - 1);
69 if((ma >= wa[u] && a) || (ma >= wa[v] && b))
70 {
71 printf("false\n");
72 continue;
73 }
74 if(a && b && (v - u) == (y - x) && (ma < wa[v]))
75 {
76 printf("true\n");
77 continue;
78 }
79 printf("maybe\n");
80 continue;
81 }
82 }