洛谷 2471 BZOJ 1067 [SCOI2007]降雨量
【题解】
用线段树维护区间最大值(因为没有修改,St表也可以),然后由于x,y可能是降雨量未知的年份,需要进行分类讨论。
1 #include<cstdio> 2 #include<algorithm> 3 #define rg register 4 #define N 50010 5 #define ls (u<<1) 6 #define rs (u<<1|1) 7 using namespace std; 8 int n,m,y[N],R[N]; 9 struct tree{ 10 int l,r,mx; 11 }a[N<<2]; 12 inline int read(){ 13 int k=0,f=1; char c=getchar(); 14 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 15 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 16 return k*f; 17 } 18 void build(int u,int l,int r){ 19 a[u].l=l; a[u].r=r; 20 if(l<r){ 21 int mid=(l+r)>>1; 22 build(ls,l,mid); build(rs,mid+1,r); 23 a[u].mx=max(a[ls].mx,a[rs].mx); 24 } 25 else a[u].mx=R[l]; 26 } 27 int query(int u,int l,int r){ 28 if(l<=a[u].l&&a[u].r<=r) return a[u].mx; 29 int ret=-2e9,mid=(a[u].l+a[u].r)>>1; 30 if(l<=mid) ret=max(ret,query(ls,l,r)); 31 if(r>mid) ret=max(ret,query(rs,l,r)); 32 return ret; 33 } 34 int main(){ 35 n=read(); 36 for(rg int i=1;i<=n;i++) y[i]=read(),R[i]=read(); 37 build(1,1,n); 38 m=read(); 39 for(rg int i=1,Mx,l2,r2;i<=m;i++){ 40 int l=read(),r=read(); 41 l2=lower_bound(y+1,y+1+n,l)-y; 42 r2=lower_bound(y+1,y+1+n,r)-y; 43 Mx=-2e9; 44 if(y[l2]!=l&&y[r2]!=r){ 45 puts("maybe"); continue; 46 } 47 if(y[l2]==l&&y[r2]!=r){ 48 if(r2-1>=l2+1) Mx=query(1,l2+1,r2-1); 49 if(Mx>=R[l2]) puts("false"); 50 else puts("maybe"); 51 } 52 if(y[l2]!=l&&y[r2]==r){ 53 if(r2-1>=l2) Mx=query(1,l2,r2-1); 54 if(Mx>=R[r2]) puts("false"); 55 else puts("maybe"); 56 } 57 if(y[l2]==l&&y[r2]==r){ 58 if(r2-1>=l2+1) Mx=query(1,l2+1,r2-1); 59 if(Mx>=R[r2]||R[l2]<R[r2]){ 60 puts("false"); continue; 61 } 62 if(y[r2]-y[l2]>r2-l2){ 63 puts("maybe"); continue; 64 } 65 puts("true"); 66 } 67 } 68 return 0; 69 }