洛谷 P2471 [SCOI2007]降雨量(RQM)

传送门


解题思路

首先判断false的情况:\(\max(a[i+1],a[j-1])>=a[j]\)
而如果i+1到j之间有没有未知降雨量的年份,则答案是maybe。
否则答案即为true。
离散化放到ST表或线段树上操作一下就行了。
情况太多了细节太多了懒得在这里写了那就说一个吧

我们常常会说这样的话:“X 年是自 Y 年以来降雨量最多的”。它的含义是 X 年的降雨量不超过 Y 年,且对于任意 Y<Z<X,Z 年的降雨量严格小于 X 年。

注意隐藏条件为Z年的降雨量也要严格小于Y年。

AC代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=50010;
int n,m,b[maxn],c[maxn],d[maxn*5];
inline void pushup(int id){
	d[id]=max(d[id*2],d[id*2+1]);
}
void update(int id,int l,int r,int x,int v){
	if(l==r){
		d[id]=v;
		return;
	}
	int mid=(l+r)/2;
	if(x<=mid) update(id*2,l,mid,x,v);
	else update(id*2+1,mid+1,r,x,v);
	pushup(id);
}
int query(int id,int l,int r,int x,int y){
	if(x>y) return 0;
	if(x<=l&&r<=y){
		return d[id];
	}
	int mid=(l+r)/2,res=0;
	if(x<=mid) res=max(res,query(id*2,l,mid,x,y));
	if(y>mid) res=max(res,query(id*2+1,mid+1,r,x,y));
	return res;
}
int main(){
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<=n;i++) {
		cin>>c[i]>>b[i];
		update(1,1,n,i,b[i]);
	}
	cin>>m;
	for(int i=1;i<=m;i++){
		int l,r;
		cin>>l>>r;
		int ll=upper_bound(c+1,c+n+1,l)-c,rr=lower_bound(c+1,c+n+1,r)-c;
		if(lower_bound(c+1,c+n+1,r)==upper_bound(c+1,c+n+1,r)){
			if(lower_bound(c+1,c+n+1,l)-c==ll){
				cout<<"maybe"<<endl;
				continue;
			}
			if(query(1,1,n,ll,rr-1)>=b[ll-1]){
				cout<<"false"<<endl;
				continue;
			}
			cout<<"maybe"<<endl;
			continue;
		}
		if(query(1,1,n,ll,rr-1)>=b[rr]){
			cout<<"false"<<endl;
			continue;
		}
		if(lower_bound(c+1,c+n+1,l)-c==ll){
			cout<<"maybe"<<endl;
			continue;
		}
		if(b[ll-1]<b[rr]){
			cout<<"false"<<endl;
			continue;
		}
		if(r-l==rr-ll+1){
			cout<<"true"<<endl;
		}else{
			cout<<"maybe"<<endl;
		} 
	}
	return 0;
}
posted @ 2021-09-15 14:56  尹昱钦  阅读(46)  评论(0编辑  收藏  举报