[BZOJ] 1067: [SCOI2007]降雨量

细节挺多的,下午脑子还算机敏

大体分四类,讨论左右端点是否存在。怎么和平衡树删除这么像

1.都不存在,肯定是maybe

2.左端点不存在,判断中间一段的最大值和右端点的关系

3.右端点不存在,判断中间一段的最大值和左端点的关系(这里有点疑惑,感觉自己写错了,居然过了)

4.都存在,先判断端点大小,再判断中间最大值(即使等于右端点也不行),再判断有没有空下的(maybe)

 

分类讨论。

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<map>
#define MAYBE puts("maybe"),0
#define TRUE puts("true"),0
#define FALSE puts("false"),0
using namespace std;

const int MAXN=100005;

inline int rd(){
  int ret=0,f=1;char c;
  while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
  while(isdigit(c))ret=ret*10+c-'0',c=getchar();
  return ret*f;
}

int n,m;
int year[MAXN];
int f[MAXN][32],val[MAXN];
map<int,int> M;

int query(int x,int y){
  if(x==y) return f[x][0];
  if(x>y) return -(1<<30);
  int len=log2(y-x+1);
  return max(f[x][len],f[y-(1<<len)+1][len]);
}

int solve(){
  int x,y,posx,posy;
  x=rd();y=rd();
  if(!M.count(x)&&!M.count(y)) return MAYBE;
  if(!M.count(x)){
    posy=M[y];posx=lower_bound(year+1,year+1+n,x)-year;
    int mx=query(posx,posy-1);//
    if(mx>=val[posy]) return FALSE;
    else return MAYBE;
  }
  if(!M.count(y)){
    posx=M[x];posy=lower_bound(year+1,year+1+n,y)-year;
    int mx=query(posx+1,posy-1);
    if(mx>=val[posx]) return FALSE;//?
    else return MAYBE;
  }
  posx=M[x];posy=M[y];
  if(val[posy]>=val[posx]) return FALSE;
  int mx=query(posx+1,posy-1);//
  if(mx>=val[posy]) return FALSE;//
  if(posy-posx!=y-x) return MAYBE;
  return TRUE;
}

int main(){
  n=rd();
  for(int i=1;i<=n;i++){
    M[year[i]=rd()]=i;f[i][0]=val[i]=rd();
  }
  for(int j=1;(1<<j)<=n;j++)
    for(int i=1;i<=n;i++)
      f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
  m=rd();

  while(m--) solve();
  return 0;
}

 

posted @ 2018-07-04 15:44  GhostCai  阅读(116)  评论(0编辑  收藏  举报