【BZOJ1067】【POJ2637】WorstWeather Ever【SCOI2007】降雨量 线段树+恶心讨论

转载请注明出处谢谢:http://blog.csdn.net/vmurder/article/details/42918883

题意:自己去BZOJ上看。

但是总之询问就是要求

// 它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年
// 左>=右>中

题解:然后首先离散化一下,然后把确定的年加到线段树中,乱搞一下就过了。

但是,,,讨论太恶心了!!


详情参照代码,写得很清晰(不清晰怎么A这道题)

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 151000
using namespace std;
struct LSH
{
	int x,y,id;
	//id/2表示询问 ,偶l奇r
	bool operator < (const LSH &a)const{return x<a.x;}
}lsh[N];
int n,m;
int ql[N],qr[N];
struct Segment_Tree
{
	int l,r,size,x;
}s[N<<2];
int val[N];
inline void pushup(int note)
{
	s[note].x=max(s[note<<1].x,s[note<<1|1].x);
	s[note].size=s[note<<1].size+s[note<<1|1].size;
}
void build(int note,int l,int r)
{
	s[note].l=l,s[note].r=r;
	if(l==r)return ;
	int mid=l+r>>1;
	build(note<<1,l,mid),build(note<<1|1,mid+1,r);
}
inline void add(int note,int pos,int x)
{
	if(s[note].l==s[note].r)
	{
		s[note].size=1;
		s[note].x=x;
		val[pos]=x;
		return ;
	}
	int mid=s[note].l+s[note].r>>1;
	if(pos<=mid)add(note<<1,pos,x);
	else add(note<<1|1,pos,x);
	pushup(note);
}
inline int query(int note,int l,int r,int &ans)
{
	if(s[note].l==l&&r==s[note].r)
	{
		ans=max(ans,s[note].x);
		return s[note].size;
	}
	int mid=s[note].l+s[note].r>>1;
	if(r<=mid)return query(note<<1,l,r,ans);
	else if(l>mid)return query(note<<1|1,l,r,ans);
	else return query(note<<1,l,mid,ans)+query(note<<1|1,mid+1,r,ans);
}
int main()
{
	freopen("test.in","r",stdin);
	int i,j,k;

	for(scanf("%d",&n),i=1;i<=n;i++)scanf("%d%d",&lsh[i].x,&lsh[i].y);
	for(scanf("%d",&m),i=1;i<=m;i++)
	{
		scanf("%d%d",&lsh[n+i*2-1].x,&lsh[n+i*2]);
		lsh[n+i*2-1].id=i*2,lsh[n+i*2].id=i*2+1;
	}n+=m*2;
	sort(lsh+1,lsh+n+1);

	int dis,now=0;
	for(i=1;i<=n;i++)
	{
		dis=lsh[i].x-lsh[i-1].x;
		if(dis==1)now++;
		else if(dis>1) now+=2;
		else if(i==1)now++;
		if(lsh[i].id)
		{
			if(lsh[i].id&1)qr[lsh[i].id>>1]=now;
			else ql[lsh[i].id>>1]=now;
			lsh[i].id=0;
		}
		else lsh[i].id=now;
	}
	build(1,1,now);
	for(i=1;i<=n;i++)if(lsh[i].id)
			add(1,lsh[i].id,lsh[i].y);
	int ans,flag;
	for(i=1;i<=m;i++)
	{// 它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年
		// 左>=右>中
		int size=0,vll=val[ql[i]],vrl=val[qr[i]];
		if(qr[i]-ql[i]>1){
			size=query(1,ql[i]+1,qr[i]-1,ans=0);
			flag=(size==qr[i]-ql[i]-1);
			// 两个都没赋值
			if(vll==0&&vrl==0)
			{
				// 只能是maybe,因为这个随便调。
				puts("maybe");
			}
			//左没值,右有值
			else if(vll==0&&vrl)
			{
				// r>mid 才可能满足条件
				if(flag||flag==0){
					if(vrl>ans)puts("maybe");
					else puts("false");
				}
		/*		else {
					if(vrl>ans)puts("maybe"); // 即使mid不确定,但是至少有个最小值
					else puts("false"); // 下面一大组情况同此
				}*/
			}
			//左有值,右没值
			else if(vll&&vrl==0)
			{
				// l>=r>mid r的取值可能很乱
				// 所以至少需要l>mid
				if(flag||flag==0){ // 这个判断条件有点厉害,思想上是这样,
					//                但是可以省掉的。
					if(vll>ans)puts("maybe");
					else puts("false");
				}
			}
			// 两个都赋值了,那么 l>=r>mid。
			else {
				// l>=r>mid
				if(flag){
					if(vll>=vrl&&vrl>ans)puts("true");
					else puts("false");
				}
				else {
					if(vll>=vrl&&vrl>ans)puts("maybe"); // 命,自有天定
					else puts("false");// 然,不争则必折也。
				}
			}
		}
		else {
			if(vll&&vrl)
			{
				if(vrl<=vll)puts("true");
				else puts("false");
			}
			else puts("maybe");
		}
	}
	return 0;
}

POJ代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 151000
using namespace std;
struct LSH
{
	int x,y,id;
	//id/2表示询问 ,偶l奇r
	bool operator < (const LSH &a)const{return x<a.x;}
}lsh[N];
int n,m;
int ql[N],qr[N];
struct Segment_Tree
{
	int l,r,size,x;
}s[N<<2];
int val[N];
void init()
{
	memset(s,0,sizeof s);
	memset(val,0,sizeof val);
	memset(lsh,0,sizeof lsh);
}
inline void pushup(int note)
{
	s[note].x=max(s[note<<1].x,s[note<<1|1].x);
	s[note].size=s[note<<1].size+s[note<<1|1].size;
}
void build(int note,int l,int r)
{
	s[note].l=l,s[note].r=r;
	if(l==r)return ;
	int mid=l+r>>1;
	build(note<<1,l,mid),build(note<<1|1,mid+1,r);
}
inline void add(int note,int pos,int x)
{
	if(s[note].l==s[note].r)
	{
		s[note].size=1;
		s[note].x=x;
		val[pos]=x;
		return ;
	}
	int mid=s[note].l+s[note].r>>1;
	if(pos<=mid)add(note<<1,pos,x);
	else add(note<<1|1,pos,x);
	pushup(note);
}
inline int query(int note,int l,int r,int &ans)
{
	if(s[note].l==l&&r==s[note].r)
	{
		ans=max(ans,s[note].x);
		return s[note].size;
	}
	int mid=s[note].l+s[note].r>>1;
	if(r<=mid)return query(note<<1,l,r,ans);
	else if(l>mid)return query(note<<1|1,l,r,ans);
	else return query(note<<1,l,mid,ans)+query(note<<1|1,mid+1,r,ans);
}
int main()
{
	int i,j,k;
	while(1)
	{
		init();
		for(scanf("%d",&n),i=1;i<=n;i++)scanf("%d%d",&lsh[i].x,&lsh[i].y);
		for(scanf("%d",&m),i=1;i<=m;i++)
		{
			scanf("%d%d",&lsh[n+i*2-1].x,&lsh[n+i*2]);
			lsh[n+i*2-1].id=i*2,lsh[n+i*2].id=i*2+1;
		}n+=m*2;
		if(n==0)return 0;
		sort(lsh+1,lsh+n+1);

		int dis,now=0;
		for(i=1;i<=n;i++)
		{
			dis=lsh[i].x-lsh[i-1].x;
			if(dis==1)now++;
			else if(dis>1) now+=2;
			else if(i==1)now++;
			if(lsh[i].id)
			{
				if(lsh[i].id&1)qr[lsh[i].id>>1]=now;
				else ql[lsh[i].id>>1]=now;
				lsh[i].id=0;
			}
			else lsh[i].id=now;
		}
		build(1,1,now);
		for(i=1;i<=n;i++)if(lsh[i].id)
				add(1,lsh[i].id,lsh[i].y);
		int ans,flag;
		for(i=1;i<=m;i++)
		{// 它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年
			// 左>=右>中
			int size=0,vll=val[ql[i]],vrl=val[qr[i]];
			if(qr[i]-ql[i]>1){
				size=query(1,ql[i]+1,qr[i]-1,ans=0);
				flag=(size==qr[i]-ql[i]-1);
				// 两个都没赋值
				if(vll==0&&vrl==0)
				{
					// 只能是maybe,因为这个随便调。
					puts("maybe");
				}
				//左没值,右有值
				else if(vll==0&&vrl)
				{
					// r>mid 才可能满足条件
					if(flag||flag==0){
						if(vrl>ans)puts("maybe");
						else puts("false");
					}
			/*		else {
						if(vrl>ans)puts("maybe"); // 即使mid不确定,但是至少有个最小值
						else puts("false"); // 下面一大组情况同此
					}*/
				}
				//左有值,右没值
				else if(vll&&vrl==0)
				{
					// l>=r>mid r的取值可能很乱
					// 所以至少需要l>mid
					if(flag||flag==0){ // 这个判断条件有点厉害,思想上是这样,
						//                但是可以省掉的。
						if(vll>ans)puts("maybe");
						else puts("false");
					}
				}
				// 两个都赋值了,那么 l>=r>mid。
				else {
					// l>=r>mid
					if(flag){
						if(vll>=vrl&&vrl>ans)puts("true");
						else puts("false");
					}
					else {
						if(vll>=vrl&&vrl>ans)puts("maybe"); // 命,自有天定
						else puts("false");// 然,不争则必折也。
					}
				}
			}
			else {
				if(vll&&vrl)
				{
					if(vrl<=vll)puts("true");
					else puts("false");
				}
				else puts("maybe");
			}
		}
		puts("");
	}

	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值