我们常常会说这样的话:“X年是自Y年以来降雨量最多的”。它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年。例如2002,2003,2004和2005年的降雨量分别为4920,5901,2832和3890,则可以说“2005年是自2003年以来最多的”,但不能说“2005年是自2002年以来最多的”由于有些年份的降雨量未知,有的说法是可能正确也可以不正确的。
我们常常会说这样的话:“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。
100%的数据满足:1<=n<=50000, 1<=m<=10000, -10^9<=yi<=10^9, 1<=ri<=10^9
#include<iostream> #include<cstdio> #include<algorithm> #include<stack> #include<cmath> using namespace std; const int maxn = 2e5 + 10; int num[maxn],rain[maxn],n,m,i,j,to[maxn]; int c[4*maxn],ql,qr; stack <int> s; void b_t(int o,int l,int r) { if (l == r) { c[o] = rain[l]; return; } int mid = (l + r) >> 1; b_t(2*o,l,mid); b_t(2*o+1,mid+1,r); c[o] = max(c[2*o],c[2*o+1]); } int Q(int o,int l,int r) { if (ql <= l && r <= qr) return c[o]; int ret = 0; int mid = (l + r) >> 1; if (ql <= mid) ret = max(ret,Q(2*o,l,mid)); if (qr > mid) ret = max(ret,Q(2*o+1,mid+1,r)); return ret; } int query(int x,int y) { ql = x,qr = y; return Q(1,1,n); } void P1(bool f) { if (f) printf("true\n"); else printf("false\n"); } void P2(bool f) { if (f) printf("maybe\n"); else printf("false\n"); } int main() { #ifdef YZY freopen("yzy.txt","r",stdin); #endif cin >> n; for (i = 1; i <= n; i++) scanf("%d%d",&num[i],&rain[i]); n++; num[n] = 2E9; rain[n] = 2E9; for (i = 1; i <= n; i++) { if (s.empty()) { s.push(i); continue; } if (num[i] - num[s.top()] > 1) { int end = s.top(); while (!s.empty()) { to[s.top()] = end; s.pop(); } } s.push(i); } if (!s.empty()) { int end = s.top(); while (!s.empty()) { to[s.top()] = end; s.pop(); } } b_t(1,1,n); cin >> m; while (m--) { int L,R; bool flag = 1,t = 0; scanf("%d%d",&L,&R); if (R <= num[1]) { P2(1); continue; } if (L >= num[n-1]) { P2(1); continue; } if (L == R) { printf("true\n"); continue; } if (L > R) { printf("false\n"); continue; } int a = lower_bound(num + 1,num + n + 1,L) - num; int b = lower_bound(num + 1,num + n + 1,R) - num; if (num[a] > L || num[b] > R || to[a] < b) flag = 0; if (flag) { if (rain[a] >= rain[b] && query(a+1,b-1) < rain[b]) t = 1; P1(t); } else { t = 1; if (num[a] == L && num[b] == R) if (rain[a] < rain[b]) t = 0; int Left = 2E9; if (num[a] == L) Left = rain[a],++a; int Right = 2E9; if (num[b] == R) Right = rain[b]; --b; int Max = query(a,b); if (Max >= Left || Max >= Right) t = 0; P2(t); } } return 0; }