hdu4614 Vases and Flowers(线段树+二分)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/bnubeginner/article/details/86538624

先呈上原题链接[HDU-4614]
题意:
有n个花瓶,每个花瓶中只能放一朵花。
两种操作:
第一种是从A开始放F朵花,如果有的花瓶中已经有花则跳过这个花瓶,往下一个花瓶放;
第二种是将区间[A,B]之间花瓶中的花清空。
如果是第一种操作,输出这次放的花的左右端点;如果是第二种操作,输出这次总共清理出了多少支花。
思路:
很裸的线段树的题啦。
用线段树维护区间花瓶空位。
第一种操作,两次二分分别寻找插花的起始位置和终止位置,再区间更新。
第二种操作直接区间更新就行了。
坑点:
其实也不算坑点啦,只是要注意下第一种操作的输入不一定其实位置能插花(我当时就是因为这个。。。算了,都怪我傻)。

good luck and have fun!!!
附上代码:

#include<bits/stdc++.h>
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define test(flag,value) cout<<flag<<":"<<(value)<<endl
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int INF=0x3f3f3f3f;
const int MAXN=1e5+5;
const int MOD=1e9+7;
const double PI=acos(-1);

int sum[MAXN<<2],lazy[MAXN<<2];
int n,m;
inline void push_up(int rt)
{
	sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void push_down(int rt,int l,int r)
{
	if(lazy[rt]==-1) return;
	int m=(l+r)>>1;
	lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
	sum[rt<<1]=(m-l+1)*lazy[rt];
	sum[rt<<1|1]=(r-m)*lazy[rt];
	lazy[rt]=-1;
}
void build(int l,int r,int rt)
{
	if(l==r)
	{
		sum[rt]=1;
		return;
	}
	int m=(l+r)>>1;
	build(l,m,rt<<1);
	build(m+1,r,rt<<1|1);
	push_up(rt);
}
void update(int L,int R,int l,int r,int rt,int val)
{
	if(L<=l&&r<=R)
	{
		sum[rt]=val*(r-l+1);
		lazy[rt]=val;
		return;
	}
	push_down(rt,l,r);
	int m=(l+r)>>1;
	if(L<=m) update(L,R,l,m,rt<<1,val);
	if(R>m)  update(L,R,m+1,r,rt<<1|1,val);
	push_up(rt);
}
int query(int L,int R,int l,int r,int rt)
{
	if(L<=l&&r<=R)
		return sum[rt];
	push_down(rt,l,r);
	int m=(l+r)>>1;
	int ret=0;
	if(L<=m) ret+=query(L,R,l,m,rt<<1);
	if(R>m)  ret+=query(L,R,m+1,r,rt<<1|1);
	return ret;
}
int bin(int st,int num)
{
	int l=st;
	int r=n;
	while(l<=r)
	{
		int m=(l+r)>>1;
		int cnt=query(st,m,1,n,1);
		if(cnt>num||(cnt==num&&query(m,m,1,n,1)==0))
			r=m;
		else if(cnt<num)
			l=m+1;
		else
		{
			return m;
		}
	}
}
int main(void)
{
	int _;scanf("%d",&_);
	while(_--)
	{
		scanf("%d%d",&n,&m);
		build(1,n,1);
		mem(lazy,-1);
		while(m--)
		{
			int k;
			scanf("%d",&k);
			if(k==1)
			{
				int f,a;
				scanf("%d%d",&a,&f);
				a++;
				int num=query(a,n,1,n,1);
				if(num==0)
					printf("Can not put any one.\n");
				else
				{
					int spos=bin(a,1);
					if(num<f)f=num;
					int epos=bin(spos,f);
					update(spos,epos,1,n,1,0);
					printf("%d %d\n", spos-1,epos-1);
				}
			}
			else if(k==2)
			{
				int l,r;
				scanf("%d%d",&l,&r);
				l++;r++;
				int ans=(r-l+1)-query(l,r,1,n,1);
				printf("%d\n", ans);
				update(l,r,1,n,1,1);
			}
		}
		printf("\n");
	}
}

猜你喜欢

转载自blog.csdn.net/bnubeginner/article/details/86538624