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 }