BZOJ1067 [SCOI2007] 降雨量

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1067

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。

 

反正我以后是不想碰这种题了

黄学长的题解:http://hzwer.com/1655.html

分类讨论真 · 多……

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cstring>
  5 #define rep(i,l,r) for(int i=l; i<=r; i++)
  6 #define clr(x,y) memset(x,y,sizeof(x))
  7 #define travel(x) for(Edge *p=last[x]; p; p=p->pre)
  8 using namespace std;
  9 typedef pair<bool,bool> pbb;
 10 const int INF = 0x3f3f3f3f;
 11 const int maxn = 50010;
 12 struct node{
 13     int l,r,mx; bool kw;
 14 }t[maxn<<2];
 15 int n,m,x,y,lnum,rnum,obj;
 16 inline int read(){
 17     int ans = 0, f = 1;
 18     char c = getchar();
 19     while (!isdigit(c)){
 20         if (c == '-') f = -1;
 21         c = getchar();
 22     }
 23     while (isdigit(c)){
 24         ans = ans * 10 + c - '0';
 25         c = getchar();
 26     }
 27     return ans * f;
 28 }
 29 inline void maintain(int w){
 30     t[w].mx = max(t[w<<1].mx,t[w<<1|1].mx);
 31     t[w].l = t[w<<1].l; t[w].r = t[w<<1|1].r;
 32     t[w].kw = t[w<<1].kw & t[w<<1|1].kw;
 33     if (t[w<<1].r + 1 != t[w<<1|1].l) t[w].kw = 0;
 34 }
 35 void build(int u,int v,int w){
 36     if (u == v){
 37         t[w].l = read(); t[w].mx = read();
 38         t[w].r = t[w].l; t[w].kw = 1; return;
 39     }
 40     int mid = (u + v) >> 1;
 41     build(u,mid,w<<1); build(mid+1,v,w<<1|1); maintain(w);
 42 }
 43 int getnum(int x,int w){
 44     if (t[w].l == t[w].r){
 45         if (t[w].l == x) return t[w].mx;
 46         return 0;
 47     }
 48     if (x <= t[w<<1].r) return getnum(x,w<<1);
 49     else if (x >= t[w<<1|1].l) return getnum(x,w<<1|1);
 50     return 0;
 51 }
 52 int pre(int x,int w){
 53     if (t[w].l == t[w].r) return t[w].l;
 54     if (x > t[w<<1|1].l) return pre(x,w<<1|1);
 55     else return pre(x,w<<1);
 56 }
 57 int nxt(int x,int w){
 58     if (t[w].l == t[w].r) return t[w].l;
 59     if (x < t[w<<1].r) return nxt(x,w<<1);
 60     else return nxt(x,w<<1|1);
 61 }
 62 pbb query(int u,int v,int w){
 63     if (t[w].l == u && t[w].r == v){
 64         return make_pair(t[w].mx < obj, t[w].kw);
 65     }
 66     if (v <= t[w<<1].r) return query(u,v,w<<1);
 67     else if (u >= t[w<<1|1].l) return query(u,v,w<<1|1);
 68     else{
 69         pbb ret1 = query(u,t[w<<1].r,w<<1); pbb ret2 = query(t[w<<1|1].l,v,w<<1|1);
 70         pbb ret = make_pair(ret1.first & ret2.first, ret1.second & ret2.second);
 71         if (t[w<<1].r  + 1 != t[w<<1|1].l) ret.second = 0;
 72         return ret;
 73     }
 74 }
 75 int main(){
 76     n = read();
 77     build(1,n,1);
 78     m = read();
 79     rep(i,1,m){
 80         x = read(); y = read();
 81         lnum = getnum(x,1), rnum = getnum(y,1);
 82         if ((!lnum) && (!rnum)){
 83             printf("maybe\n"); continue;
 84         }
 85         else{
 86             int lnxt = nxt(x,1), rpre = pre(y,1);
 87             if (!lnum){
 88                 obj = rnum;
 89                 if (lnxt > rpre || rpre == y){
 90                     printf("maybe\n");
 91                     continue;
 92                 }
 93                 pbb f = query(lnxt,rpre,1);
 94                 if (!f.first) printf("false\n");
 95                 else printf("maybe\n");
 96             }
 97             else if (!rnum){
 98                 obj = lnum;
 99                 if (lnxt > rpre || lnxt == x){
100                     printf("maybe\n");
101                     continue;
102                 }
103                 pbb f = query(lnxt,rpre,1);
104                 if (!f.first) printf("false\n");
105                 else printf("maybe\n");
106             }
107             else{
108                 obj = rnum;
109                 if (lnum >= rnum){
110                     if (lnxt > rpre){
111                         if (x + 1 == y) printf("true\n");
112                         else printf("maybe\n");
113                         continue;
114                     }
115                     pbb f = query(lnxt,rpre,1);
116                     if (!f.first) printf("false\n");
117                     else if (f.first && f.second){
118                         if (lnxt - 1 == x && rpre + 1 == y) printf("true\n");
119                         else printf("maybe\n");
120                     }
121                     else printf("maybe\n");
122                 }
123                 else printf("false\n");
124             }
125         }
126     }
127     return 0;
128 }
View Code

posted on 2016-01-03 14:19  ACMICPC  阅读(265)  评论(0编辑  收藏  举报

导航