题目描述
我们常常会说这样的话:“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
<water[y]是就是这种情况。
但是。。。该怎么判断一个区间内有没有不知道的年份呀。。。
因为年份在输入的时候就保证了一定是升序的,那么如果x的编号-y的编号=x-y,就代表这个区间内没有不知道
的。
然后剩下的再维护一下rmq就好了,但是我开始写的线段树不知道为什么全MLE了,所以我用的是ST表。
Code
#include <bits/stdc++.h>
using namespace std;
const int max_n=50000+5;
const int inf=1e9;
int N,M;
int year[max_n],water[max_n];
inline int read()
{
register int x=0,v=1;
register char ch=getchar();
while(!isdigit(ch))
{
if(ch==‘-‘) v=-1;
ch=getchar();
}
while(isdigit(ch))
{
x=(x<<1)+(x<<3)+ch-‘0‘;
ch=getchar();
}
return x*v;
}
class ST
{
private:
int table[30][max_n],lg2[max_n];
public:
inline void build()
{
lg2[0]=-1;
for(register int i=1;i<=N;++i)
{
year[i]=read(),water[i]=table[0][i]=read();
lg2[i]=lg2[i>>1]+1;
}
for(register int i=1;i<=20;++i)
{
for(register int j=1;j+(1<<i)-1<=N;++j)
{
table[i][j]=max(table[i-1][j],table[i-1][j+(1<<i-1)]);
}
}
return;
}
inline int query(int l,int r)
{
if(l>r) return -inf;
int lg=lg2[r-l+1];
return max(table[lg][l],table[lg][r-(1<<lg)+1]);
}
};
inline int getw(int x)
{
int l=1,r=N,mid;
while(l<r)
{
mid=l+r>>1;
if(year[mid]>=x) r=mid;
else l=mid+1;
}
return l;
}
int main()
{
int x,y,idx,idy,jx,jy,t;
ST st;
N=read();
st.build();
M=read();
for(register int i=1;i<=M;++i)
{
x=read(),y=read();
idx=getw(x),idy=getw(y);
jx=(year[idx]==x),jy=(year[idy]==y);
t=st.query(idx+1,idy-1);
if(jx)
{
if(jy)
{
if(water[idx]<water[idy]) puts("false");
else if(t<water[idy])
{
if(y-x==idy-idx) puts("true");
else puts("maybe");
}
else puts("false");
}
else
{
if(t<water[idx]) puts("maybe");
else puts("false");
}
}
else
{
if(jy)
{
t=st.query(idx,idy-1);
if(t<water[idy]) puts("maybe");
else puts("false");
}
else puts("maybe");
}
}
return 0;
}
博主是蒟蒻,有错误请指出,谢谢!