[SCOI2007] 降雨量

link

动态开点线段树的板子,然后支持查询区间最大值。坑点比较多,要判断的东西也很多,比如后来的年份或者之前的年份只有一个不知道的情况下答案可能是false而不是maybe,要和区间内最大值进行比较之后才能获得答案。其它一些细节对着大样例调就可以了……吧?反正考场上写挂了。今天的考试集中反映了我的愚蠢。

#include<bits/stdc++.h>
//#define feyn
const int N=50010;
const int maxn=1e9;
using namespace std;
inline void read(int &wh){
	wh=0;int f=1;char w=getchar();
	while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
	while(w>='0'&&w<='9'){wh=wh*10+w-'0';w=getchar();}
	wh*=f;return;
}
inline int max(int s1,int s2){
	return s1<s2?s2:s1;
}

#define lc t[wh].left
#define rc t[wh].right
#define mid (l+r>>1)
struct node{
	int left,right,data,size;
}t[N*20];
int cnt,root;
inline void pushup(int wh){
	t[wh].data=max(t[lc].data,t[rc].data);
	t[wh].size=t[lc].size+t[rc].size;
}
inline void insert(int &wh,int l,int r,int pl,int data){
	if(wh==0)wh=++cnt;
	if(l==r){t[wh].data=data;t[wh].size=1;return;}
	if(pl<=mid)insert(lc,l,mid,pl,data);
	else insert(rc,mid+1,r,pl,data);
	pushup(wh);return;
}
inline int find(int wh,int l,int r,int pl){
	if(!wh)return -1;
	return l==r?t[wh].data:(pl<=mid?find(lc,l,mid,pl):find(rc,mid+1,r,pl));
}
struct an{int data,size;};
inline an operator +(an s1,an s2){
	return (an){max(s1.data,s2.data),s1.size+s2.size};
}
inline an work(int wh,int l,int r,int wl,int wr){
	//printf("%d %d %d %d\n",l,r,wl,wr);
	if(wr<wl||wh==0)return (an){-1,0};
	if(wl<=l&&r<=wr)return (an){t[wh].data,t[wh].size};
	an ans=(an){-1,0};
	if(wl<=mid)ans=ans+work(lc,l,mid,wl,wr);
	if(wr>mid)ans=ans+work(rc,mid+1,r,wl,wr);
	return ans;
}
#undef lc
#undef rc
#undef mid

signed main(){
	
	#ifdef feyn
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
	#endif
	
	int m,a,b;
	read(m);
	while(m--){
		read(a);read(b);
		insert(root,-maxn,maxn,a,b);
	}
	read(m);
	while(m--){
		read(a);read(b);
		an now=work(1,-maxn,maxn,a+1,b-1);
		int va=find(1,-maxn,maxn,a),vb=find(1,-maxn,maxn,b);
		if(now.data>=vb&&vb>=0){printf("false\n");continue;}
		if(now.data>=va&&va>=0){printf("false\n");continue;}
		if(va==-1||vb==-1){printf("maybe\n");continue;}
		if(va<vb){printf("false\n");continue;}
		if(a+1==b){printf("true\n");continue;}
		if(now.size==b-a-1)printf("true\n");
		else printf("maybe\n");
	}
	
	return 0;
}
posted @ 2022-07-08 17:31  Feyn618  阅读(14)  评论(0编辑  收藏  举报