洛谷 P2471 [SCOI2007]降雨量
在神贴题单里看到了这道题,就拿出来做了。
题目思路比较明显对,年份离散化,年份也是单调递增的。很明显,我们
是需要维护年份区间最大的,可以利用线段树或者st表维护,针对每一组
询问,我们由已知条件来分类讨论即可,分类讨论比较复杂,需要注意细
节
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=1e5;
inline int read(){
int ret=0;
int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-f;
ch=getchar();
}
while(ch<='9'&&ch>='0'){
ret=ret*10+(ch^'0');
ch=getchar();
}
return f*ret;
}
int n,m;
int a[maxn];
int v[maxn];
struct node{
int val;
}tre[maxn*4];
void build(int rt,int l,int r){
if(l==r){
tre[rt].val=v[l];
return;
}
int mid=(l+r)>>1;
build(rt*2,l,mid);
build(rt*2+1,mid+1,r);
tre[rt].val=max(tre[rt*2].val,tre[rt*2+1].val);
}
int query(int rt,int l,int r,int ql,int qr){
if(l>qr||r<ql){
return 0 ;
}
if(l>=ql&&r<=qr){
return tre[rt].val;
}
int mid=(l+r)>>1;
int ans=-1;
if(ql<=mid){
ans=max(ans,query(rt*2,l,mid,ql,qr));
}
if(qr>mid){
ans=max(ans,query(rt*2+1,mid+1,r,ql,qr));
}
return ans;
}
int main(){
freopen("a.in","r",stdin);
n=read();
// cout<<n<<endl;
for(int i=1;i<=n;i++){
a[i]=read();
v[i]=read();
}
build(1,1,n);
m=read();
int ye;
int val;
int st=0,la=0;
int stt;
int laa;
for(int i=1;i<=m;i++){
stt=read();
laa=read();//获得年份 a,b;
st=lower_bound(a+1,a+1+n,stt)-a;//在年份表内查找出对应年份的下标
la=lower_bound(a+1,a+1+n,laa)-a;
int le=laa-stt+1;
int f1=0;
int f2=0;
int maxx=-1;
if(a[st]!=stt){//过没查到,就是没有该元素
f1=1;//做标记
}
if(a[la]!=laa){
f2=1;
}
if(f1&&f2){//如果两个元素都没有
cout<<"maybe"<<endl;//无法确定判断是否正确
continue;
}
if(!f1&&!f2){//如果两个年份都有
if(v[st]<=v[la]){//如果 b年的降雨量大于等于a的,错误
cout<<"false"<<endl;
continue;
}
int len=laa-stt;//求出实际年份差
if(len==1){//假设两年的实际差值为一
if(v[la]<v[st]){
cout<<"true"<<endl;//如果b年小于a年符合题意
}
else {
cout<<"false"<<endl;
}
continue;
}
if(la-st==1){//如果两年内部年份全部未知
cout<<"maybe"<<endl;
continue;
}
maxx=query(1,1,n,st+1,la-1);
if(maxx>=v[la]){//a,b年份内已知区间内出现最大年份大于b
cout<<"false"<<endl;
continue;
}
else{
if(le==la-st+1)
cout<<"true"<<endl;
else{
cout<<"maybe"<<endl;
}
continue;
}
}
if(f1&&!f2){//如果a未知,b已知
if(st==la){//如果区间内全未知
cout<<"maybe"<<endl;
continue;
}
maxx=query(1,1,n,st,la-1);
if(maxx>=v[la]){
cout<<"false"<<endl;
}
else
cout<<"maybe"<<endl;//由于我们不知道A,所以无法确定
continue;
}
if(!f1&&f2){//第一个已知,第二个未知
if(la-1==st){//如果询问区间全未知
cout<<"maybe"<<endl;
continue;
}
maxx=query(1,1,n,st+1,la-1);
if(maxx>=v[st]){
cout<<"false"<<endl;
}
else{
cout<<"maybe"<<endl;
}
continue;
}
}
return 0;
}