洛谷P2471——[SCOI2007]降雨量
本机AC提交RE……
传送门:QAQQAQ
题意:自己看
思路:据说这道题用RMQ做很快,但这道题线段树是可以的
线段树维护一段区间最左年,最右年,是否有间隙和区间最大值
这道题分类讨论是一大难点,主要分为以下几种情况:
1.AB均不确定,输出maybe
2.A确定B不确定:
若A是A到B最大的,输出maybe
否则输出false
3.A不确定B确定:
若B是lower_bound(A)到B最大的,则输出maybe
否则输出false
4.A确定B确定
若B是A+1到B最大的,A是A到B最大的,且之间没有间隙,输出true
若满足上述条件,但有间隙,则输出maybe
否则输出false
在代码实现方面,我先是没有考虑“严格小于”这一条件,认为最大值等于B就行了,而没有判断之前有无相等
然后加了一些特判防止自己玄学线段树越界停不下来。。。(最近代码实现能力有待提升啊。。。)
代码:
#include<bits/stdc++.h> using namespace std; const int N=100005; int n; struct node { int ly,ry,max_r,Gap; }tree[N*4]; int rain[N],year[N]; void push_up(node& fa,node ls,node rs) { fa.ly=ls.ly; fa.ry=rs.ry; fa.max_r=max(ls.max_r,rs.max_r); fa.Gap=0; if(ls.Gap||rs.Gap) fa.Gap=1; if(ls.ry+1<rs.ly) fa.Gap=1; } void build(int x,int l,int r) { if(l==r) { tree[x].ly=year[l]; tree[x].ry=year[l]; tree[x].max_r=rain[l]; tree[x].Gap=0; return; } int mid=(l+r)>>1; build(x+x,l,mid); build(x+x+1,mid+1,r); push_up(tree[x],tree[x+x],tree[x+x+1]); } node query(int x,int l,int r,int L,int R) { node ret; if(L<=l&&R>=r) return tree[x]; int mid=(l+r)>>1; if(mid<L) return query(x+x+1,mid+1,r,L,R); if(mid>=R) return query(x+x,l,mid,L,R); node ls=query(x+x,l,mid,L,R); node rs=query(x+x+1,mid+1,r,L,R); push_up(ret,ls,rs); return ret; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d",&year[i],&rain[i]); build(1,1,n); int q; scanf("%d",&q); while(q--) { int x,y,xx,yy,bl=0; scanf("%d%d",&xx,&yy); if(yy<xx) { puts("false"); continue; } if(xx==yy) { puts("maybe"); continue; } x=lower_bound(year+1,year+n+1,xx)-year; y=lower_bound(year+1,year+n+1,yy)-year; if(xx!=year[x]&&yy!=year[y]) puts("maybe"); else if(xx!=year[x]) { if(y==1||x==y) puts("maybe"); else { node n1=query(1,1,n,x,y); node n2=query(1,1,n,x,y-1); //中间降雨量必须严格小于! if(n1.max_r==rain[y]&&n2.max_r<rain[y]) puts("maybe"); else puts("false"); } } else if(yy!=year[y]) { if(x==n||x==y-1) puts("maybe"); else { node n1=query(1,1,n,x,y-1); node n2=query(1,1,n,x+1,y-1); if(n1.max_r==rain[x]&&n2.max_r<rain[x]) puts("maybe"); else puts("false"); } } else { if(x+1==y) { if(rain[x]<rain[y]) puts("false"); else if(year[x]+1==year[y]) puts("true"); else puts("maybe"); continue;//之前没写continue啊啊啊。。。 }//特判防止线段树越界 node n1=query(1,1,n,x,y); node n2=query(1,1,n,x+1,y); node n3=query(1,1,n,x+1,y-1); if(n2.max_r==rain[y]&&rain[y]<=rain[x]&&n3.max_r<rain[y]) { if(n1.Gap) puts("maybe"); else puts("true"); } else puts("false"); } } return 0; }