我们常常会说这样的话:“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
RMQ。
维护区间最大值即可。
对于年份,我用map保存,若相邻的年份之间有未知的,把他们缩成一年,于是对于一个区间是否全部已知,用前缀和判断即可。
一些实现上的细节:
1.对于查询,可能会问到未知的年份,需要通过二分查找确定他在map中的对应值
2.若x,y未知,直接特判处理(若x未知,可能是maybe,可能是false!!)
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <cmath> #include <map> #define M 50005 using namespace std; map<int,int> mp; int f[M*2][20],r[M*2],now,R[M],y[M],sum[M*2],n,m; void RMQ() { for (int i=1;i<=now;i++) f[i][0]=r[i]; for (int j=1;(1<<j)<=now;j++) for (int i=1;i+(1<<j)-1<=now;i++) f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]); } int Getlog(int x) { if (x==1) return 0; int b=1; for (int i=0;;i++) { if (x>b&&x<=b*2) return i; b*=2; } } int Getmax(int l,int r) { if (r<l) return 0; int s=Getlog(r-l+1); return max(f[l][s],f[r-(1<<s)+1][s]); } int Get(int x) { int l=0,r=n,ans=0; while (l<=r) { int m=(l+r)>>1; if (y[m]<x) ans=m,l=m+1; else r=m-1; } return mp[y[ans]]+1; } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d%d",&y[i],&R[i]); y[0]=-1e9-1; mp[y[0]]=0; mp[y[1]]=2; r[2]=R[1]; sum[2]=1; for (int i=2;i<=n;i++) { now=mp[y[i-1]]+1; if (y[i]>y[i-1]+1) now++; mp[y[i]]=now; r[now]=R[i]; sum[now]=1; } for (int i=1;i<=now;i++) sum[i]=sum[i]+sum[i-1]; RMQ(); scanf("%d",&m); while (m--) { int x,y; scanf("%d%d",&y,&x); if (!mp.count(y)) y=Get(y); else y=mp[y]; if (!mp.count(x)) x=Get(x); else x=mp[x]; int k=Getmax(y+1,x-1); if (!r[x]) { if (!r[y]||!k||r[y]>k) puts("maybe"); else puts("false"); continue; } if (r[x]<=r[y]||!r[y]) { if (k>=r[x]) puts("false"); else { if (sum[x]-sum[y-1]==x-y+1) puts("true"); else puts("maybe"); } } else puts("false"); } return 0; }
原文地址:http://blog.csdn.net/regina8023/article/details/43899691