【线段树 细节题】bzoj1067: [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


 

题目分析

题意很简单,但是一道需要细细思考的细节题。

具体的思路,挂一个很详细的博客好了题解 P2471 【[SCOI2007]降雨量】

至于具体实现我用了离散化,然后用线段树查询(x,y)区间内的最值。

  1 #include<bits/stdc++.h>
  2 const int maxn = 50035;
  3 
  4 struct QRs
  5 {
  6     int x,y;
  7 }qr[10035];
  8 struct node
  9 {
 10     int x,val;
 11 }a[maxn];
 12 int n,m;
 13 int tot[100035],t[100035],cnt;
 14 int val[100035],f[400035];
 15 
 16 int read()
 17 {
 18     char ch = getchar();
 19     int num = 0;
 20     bool fl = 0;
 21     for (; !isdigit(ch); ch = getchar())
 22         if (ch=='-') fl = 1;
 23     for (; isdigit(ch); ch = getchar())
 24         num = (num<<1)+(num<<3)+ch-48;
 25     if (fl) num = -num;
 26     return num;
 27 }
 28 void pushup(int x)
 29 {
 30     f[x] = std::max(f[x<<1], f[x<<1|1]);
 31 }
 32 void build(int rt, int l, int r)
 33 {
 34     if (l==r){
 35         f[rt] = val[l];
 36         return;
 37     }
 38     int mid = (l+r)>>1;
 39     build(rt<<1, l, mid), build(rt<<1|1, mid+1, r);
 40     pushup(rt);
 41 }
 42 int query(int rt, int L, int R, int l, int r)
 43 {
 44     if (L > R) return 0;
 45     if (L <= l&&r <= R) return f[rt];
 46     int mid = (l+r)>>1, ret = 0;
 47     if (L <= mid) ret = query(rt<<1, L, R, l, mid);
 48     if (R > mid)
 49         ret = std::max(ret, query(rt<<1|1, L, R, mid+1, r));
 50     return ret;
 51 }
 52 int main()
 53 {
 54     n = read();
 55     for (int i=1; i<=n; i++)
 56         t[++cnt] = a[i].x = read(), a[i].val = read();
 57     m = read();
 58     for (int i=1; i<=m; i++)
 59         t[++cnt] = qr[i].x = read(), t[++cnt] = qr[i].y = read(), t[++cnt] = qr[i].y-1, t[++cnt] = qr[i].x+1;
 60     std::sort(t+1, t+cnt+1);
 61     cnt = std::unique(t+1, t+cnt+1)-t-1;
 62     int pre = 0;
 63     for (int i=1; i<=n; i++)
 64     {
 65         int tt = std::lower_bound(t+1, t+cnt+1, a[i].x)-t;
 66         val[tt] = a[i].val, tot[tt] = tot[pre]+1, pre = tt;
 67     }
 68     build(1, 1, cnt);
 69     for (int i=1; i<=m; i++)
 70     {
 71         int x = std::lower_bound(t+1, t+cnt+1, qr[i].x)-t;
 72         int y = std::lower_bound(t+1, t+cnt+1, qr[i].y)-t;
 73         int dex = std::lower_bound(t+1, t+cnt+1, qr[i].x+1)-t;
 74         int dey = std::lower_bound(t+1, t+cnt+1, qr[i].y-1)-t;
 75         if (val[x]&&val[y]){
 76             if (val[x] < val[y]) puts("false");
 77             else{
 78                 bool exCheck = query(1, dex, dey, 1, cnt)<val[y];
 79                 if (!exCheck) puts("false");
 80                 else{
 81                     exCheck = exCheck&&((tot[y]-tot[x])==(qr[i].y-qr[i].x));
 82                     if (!exCheck) puts("maybe");
 83                     else puts("true");
 84                 }
 85             }
 86             continue;
 87         }
 88         if ((!val[x])&&(!val[y])) puts("maybe");
 89         else{
 90             int secMx = query(1, dex, dey, 1, cnt);
 91             if (!secMx){
 92                 puts("maybe");
 93                 continue;
 94             }
 95             if (val[x]){
 96                 if (secMx >= val[x]) puts("false");
 97                 else puts("maybe");        //注意这里是maybe而不是true因为中间值未知
 98             }
 99             if (val[y]){
100                 if (secMx >= val[y]) puts("false");
101                 else puts("maybe");
102             }
103         }
104     }
105     return 0;
106 }

 

 

END

posted @ 2018-07-23 15:25  AntiQuality  阅读(228)  评论(0编辑  收藏  举报