BZOJ1067 [SCOI2007]降雨量 模拟/线段树/map经验书

从知道x,y能是没出现过的我就知道GG了

之前写的版本耦合太强,完全改不过来只好推掉重写。。

学到了max_element以及map的一些坑

map的lower_bound熟练度++

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<iomanip>
#include<stack>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mem(a) memset(a,0,sizeof a)
#define FOR(a) for(int i=1;i<=a;i++)
#define sqr(a) (a)*(a)
 
const int maxn=5e4+7;
const int inf=0x3f3f3f3f;

int n,q;
int tot;

struct dot{
	int y,r,id;;
}arr[maxn];

int a[maxn];	//id   -> 降雨量
map<int,int>b;	//年份 -> id

struct NODE{
	bool unk;
	int mx;
}ST[maxn<<2];

void pushup(int rt){
	ST[rt].unk=(ST[rt<<1].unk | ST[rt<<1|1].unk);
	ST[rt].mx=max(ST[rt<<1].mx,ST[rt<<1|1].mx);
}
void build(int l,int r,int rt){
	if(l==r){
		if(a[l]==0){ST[rt].unk=1;ST[rt].mx=-inf;}
		else{ST[rt].unk=0;ST[rt].mx=a[l];}
		return;
	}
	int m=l+r>>1;build(l,m,rt<<1);build(m+1,r,rt<<1|1);pushup(rt);
}
int queryMX(int a,int b,int l,int r,int rt){
	if(a<=l&&b>=r){return ST[rt].mx;}
	int ans=-inf;
	int m=l+r>>1;
	if(a<=m)ans=queryMX(a,b,l,m,rt<<1);
	if(b>m)ans=max(ans,queryMX(a,b,m+1,r,rt<<1|1));
	return ans;
}
bool queryUN(int a,int b,int l,int r,int rt){
	if(a<=l&&b>=r){return ST[rt].unk;}
	int m=l+r>>1;
	if(a<=m)if(queryUN(a,b,l,m,rt<<1))return true;
	if(b>m)if(queryUN(a,b,m+1,r,rt<<1|1))return true;
	return false;
}

int maxY=-inf,minY=inf;

int work(int x,int y){	// y是x之后降雨最高	
	bool havx=b.count(x),havy=b.count(y);

	//cout<<havx<<" "<<havy<<endl;

	map<int,int>::iterator lwbx=b.lower_bound(x);
	map<int,int>::iterator higx=b.upper_bound(x);
	map<int,int>::iterator lwby=b.lower_bound(y);
	map<int,int>::iterator higy=b.upper_bound(y);
	lwbx--;map<int,int>::iterator lesx=lwbx;lwbx++;
	lwby--;map<int,int>::iterator lesy=lwby;lwby++;

	int idx=b[x],idy=b[y];

	if(!havx && !havy)return 3;
	if(havy && havx){
		if(		a[idx]>=a[idy] &&(
					idx+1==idy ||
					(a[idy]>queryMX(idx+1,idy-1,1,tot,1) &&
					!queryUN(idx+1,idy-1,1,tot,1)
					)
				)
			)return 1;
		if(		a[idx]>=a[idy] &&
				a[idy]>queryMX(idx+1,idy-1,1,tot,1) &&
				queryUN(idx+1,idy-1,1,tot,1)
			)return 3;
		return 2;
	}
	//x,y其一出现
	if(havx){	//!havy

		if(higx == lwby){return 3;}

		if(idx==tot)return 3;
		if(lwby==b.end()){			
			if(queryMX(idx+1,b[maxY],1,tot,1) < a[idx])return 3;
			else return 2;
		}else{
			if(queryMX(idx+1,lesy->second,1,tot,1) < a[idx])return 3;
			else return 2;
		}
	}
	if(havy){
		
		if(higx == lwby){return 3;}

		if(b[y]==1)return 3;
		if(queryMX(higx->second,idy-1,1,tot,1) < a[idy])return 3;
		else return 2;
	}
}

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){scanf("%d%d",&arr[i].y,&arr[i].r);}
	
	arr[1].id=1;
	b[arr[1].y]=1;
	a[1]=arr[1].r;

	for(int i=2;i<=n;i++){
		if(arr[i].y-arr[i-1].y>1){
			arr[i].id=arr[i-1].id+2;
			a[arr[i].id]=arr[i].r;
			b[arr[i].y]=arr[i].id;
		}
		else {
			arr[i].id=arr[i-1].id+1;
			a[arr[i].id]=arr[i].r;
			b[arr[i].y]=arr[i].id;
		}
	}
	maxY=max_element(b.begin(),b.end())->first;
	minY=min_element(b.begin(),b.end())->first;

	tot=arr[n].id;
	build(1,tot,1);

	scanf("%d",&q);
	while(q--){
		int x,y;scanf("%d%d",&x,&y);

		bool misx=b.count(x),misy=b.count(y);

		if(y<x){puts("false");continue;}
		int flag=work(x,y);
		if(flag==1)puts("true");
		else if(flag==2)puts("false");
		else puts("maybe");

		if(!misx)b.erase(x);
		if(!misy)b.erase(y);
	}
}


posted @ 2017-11-15 23:57  Drenight  阅读(115)  评论(0编辑  收藏  举报