HDU-4614 Vases and Flowers (线段树区间更新)

Posted 真正的强者,从不埋怨黎明前的黑暗!!!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU-4614 Vases and Flowers (线段树区间更新)相关的知识,希望对你有一定的参考价值。

题目大意:有n个花瓶,每个花瓶中只能放一朵花。两种操作,一种是从A开始放F朵花,如果有的花瓶中已经有花则跳过这个花瓶,往下一个花瓶放;第二种是将区间[A,B]之间花瓶中的花清空。如果是第一种操作,输出这次放的花的左右端点;如果是第二种操作,输出这次总共清理出了多少支花。

题目分析:建立线段树,节点维护在相应的区间中,没有放入花的花瓶数目。有三种操作:一、查询某个区间中第k个没有插入花的花瓶位置;二、更新区间,使区间全部插入花;三、更新区间,使区间中的花瓶全部清空;

 

代码如下:

# include<iostream>
# include<cstdio>
# include<queue>
# include<vector>
# include<list>
# include<map>
# include<set>
# include<cstdlib>
# include<string>
# include<cstring>
# include<algorithm>
using namespace std;
# define LL long long

const int N=50100;
const int INF=1<<30;
const double oo=1e20;
const double eps=1e-20;

int lazy[N*4+5];
int tr[N*4+5];

void pushDown(int rt,int l,int r)
{
	if(lazy[rt]!=-1){
		lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
		if(lazy[rt]==1)
			tr[rt<<1]=tr[rt<<1|1]=0;
		else{
			int mid=l+(r-l)/2;
			tr[rt<<1]=mid-l+1;
			tr[rt<<1|1]=r-mid;
		}
		lazy[rt]=-1;
	}
}

void pushUp(int rt)
{
	tr[rt]=tr[rt<<1]+tr[rt<<1|1];
}

void build(int rt,int l,int r)
{
	tr[rt]=r-l+1;
	lazy[rt]=-1;
	if(l==r)
		return ;
	int mid=l+(r-l)/2;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid+1,r);
}

void update(int rt,int l,int r,int L,int R)
{
	if(L<=l&&r<=R){
		tr[rt]=0;
		lazy[rt]=1;
	}else{
		pushDown(rt,l,r);
		int mid=l+(r-l)/2;
		if(L<=mid) update(rt<<1,l,mid,L,R);
		if(R>mid) update(rt<<1|1,mid+1,r,L,R);
		pushUp(rt);
	}
}

int clear(int rt,int l,int r,int L,int R)
{
	if(L<=l&&r<=R){
		int temp=tr[rt];
		tr[rt]=r-l+1;
		lazy[rt]=0;
		return tr[rt]-temp;
	}else{
		pushDown(rt,l,r);
		int mid=l+(r-l)/2;
		int res=0;
		if(L<=mid) res+=clear(rt<<1,l,mid,L,R);
		if(R>mid) res+=clear(rt<<1|1,mid+1,r,L,R);
		pushUp(rt);
		return res;
	}
}

int query(int rt,int l,int r,int L,int R)
{
	if(L>r||R<l) return 0;	///这句话必须加上,否则query可能会一直被调用下去
	if(L<=l&&r<=R)
		return tr[rt];
	pushDown(rt,l,r);
	int mid=l+(r-l)/2;
	int res=0;
	if(L<=mid)
		res+=query(rt<<1,l,mid,L,R);
	if(R>mid)
		res+=query(rt<<1|1,mid+1,r,L,R);
	return res;
}

int ask(int rt,int l,int r,int L,int R,int num)
{
	if(l==r){
		return l;
	}else{
		pushDown(rt,l,r);
		int mid=l+(r-l)/2;
		int t=query(rt<<1,l,mid,L,R);
		if(num<=t) return ask(rt<<1,l,mid,L,R,num);
		return ask(rt<<1|1,mid+1,r,L,R,num-t);
	}
}

int main()
{
	int T,n,m;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&n,&m);
		build(1,1,n);
		int k,a,b;
		while(m--)
		{
			scanf("%d%d%d",&k,&a,&b);
			if(k==1){
				int t=query(1,0,n-1,a,n-1);
				if(t==0)
					printf("Can not put any one.\n");
				else{
					int l=ask(1,0,n-1,a,n-1,1);
					int r=ask(1,0,n-1,a,n-1,min(b,t));
					printf("%d %d\n",l,r);
					update(1,0,n-1,l,r);
				}
			}else{
				int ans=clear(1,0,n-1,a,min(n-1,b));
				printf("%d\n",ans);
			}
		}
		printf("\n");
	}
	return 0;
}

  

以上是关于HDU-4614 Vases and Flowers (线段树区间更新)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 4614 Vases and Flowers 线段树+二分

hdu 4614 Vases and Flowers

Vases and Flowers HDU - 4614

HDU4614Vases and Flowers 二分+线段树;

HDU-4614 Vases and Flowers (线段树区间更新)

Vases and Flowers HDU - 4614线段树+主席树思维/二分