我们常常会说这样的话:“X年是自Y年以来降雨量最多的”。它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年。例如2002,2003,2004和2005年的降雨量分别为4920,5901,2832和3890,则可以说“2005年是自2003年以来最多的”,但不能说“2005年是自2002年以来最多的”由于有些年份的降雨量未知,有的说法是可能正确也可以不正确的。
Solution
考虑问题的主要限制,l>=r>(l到r的所有数)。
首先,如果l=r,那么肯定是合法的。
然后直接判如果l<r,干掉。
再判l+1=r.如果l和r都已知,那么就true,否则maybe。
再判一下l到r之间有没有数,如果没有,就maybe。
如果没有r的情况得特判一下,l和r之间最大值大于l(这个很重要),干掉,否则maybe。
然后再判中间的数和r的关系,和l是否有值,还有区间长度。
真**恶心。
Code
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<algorithm> #define N 50002 #define mm make_pair using namespace std; int p[N][20],n,num1,num2,num3,iid,id[N],q,iiid; inline int calc(int l,int r){ int lo=log(r-l+1)/log(2); return max(p[l][lo],p[r-(1<<lo)+1][lo]); } int main(){ scanf("%d",&n);int x,y; for(int i=1;i<=n;++i)scanf("%d%d",&id[i],&p[i][0]); for(int i=1;(1<<i)<=n;++i) for(int j=1;j+(1<<i)-1<=n;++j) p[j][i]=max(p[j][i-1],p[j+(1<<i-1)][i-1]); scanf("%d",&q); while(q--){ scanf("%d%d",&x,&y); if(x==y){ printf("true "); continue; } num1=upper_bound(id+1,id+n+1,x)-id; num2=lower_bound(id+1,id+n+1,y)-id-1; iid=num2+1;iiid=num1-1; if(id[iid]==y&&id[iiid]==x&&p[iid][0]>p[iiid][0]){ printf("false "); continue; } if(x+1==y){ if(id[iid]==y&&id[iiid]==x) printf("true "); else printf("maybe "); continue; } if(num1>num2){ printf("maybe "); continue; } if(id[iid]!=y){ if(id[iiid]!=x){ printf("maybe "); continue; } num3=calc(num1,num2); if(num3>=p[iiid][0]){ printf("false "); continue; } printf("maybe "); continue; } num3=calc(num1,num2); if(num3>=p[iid][0]){ printf("false "); continue; } if(id[iiid]!=x){ printf("maybe "); continue; } if(num2-num1!=(y-1)-(x+1))printf("maybe "); else printf("true "); } return 0; }
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<algorithm> #define N 50002 #define mm make_pair using namespace std; int p[N][20],n,num1,num2,num3,iid,id[N],q,iiid; inline int calc(int l,int r){ int lo=log(r-l+1)/log(2); return max(p[l][lo],p[r-(1<<lo)+1][lo]); } int main(){ scanf("%d",&n);int x,y; for(int i=1;i<=n;++i)scanf("%d%d",&id[i],&p[i][0]); for(int i=1;(1<<i)<=n;++i) for(int j=1;j+(1<<i)-1<=n;++j) p[j][i]=max(p[j][i-1],p[j+(1<<i-1)][i-1]); scanf("%d",&q); while(q--){ scanf("%d%d",&x,&y); if(x==y){ printf("true "); continue; } num1=upper_bound(id+1,id+n+1,x)-id; num2=lower_bound(id+1,id+n+1,y)-id-1; iid=num2+1;iiid=num1-1; if(id[iid]==y&&id[iiid]==x&&p[iid][0]>p[iiid][0]){ printf("false "); continue; } if(x+1==y){ if(id[iid]==y&&id[iiid]==x) printf("true "); else printf("maybe "); continue; } if(num1>num2){ printf("maybe "); continue; } if(id[iid]!=y){ if(id[iiid]!=x){ printf("maybe "); continue; } num3=calc(num1,num2); if(num3>=p[iiid][0]){ printf("false "); continue; } printf("maybe "); continue; } num3=calc(num1,num2); if(num3>=p[iid][0]){ printf("false "); continue; } if(id[iiid]!=x){ printf("maybe "); continue; } if(num2-num1!=(y-1)-(x+1))printf("maybe "); else printf("true "); } return 0; }