我们常常会说这样的话:“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