其他分享
首页 > 其他分享> > P2894 [USACO08FEB]Hotel G

P2894 [USACO08FEB]Hotel G

作者:互联网

written on 2022-05-14

写这篇题解的原因是cpp说我基础太烂,于是找几题巩固。

一道巩固线段树基础的好题。同P3071好评

审完题后,发现有许多区间操作,所以很明显是用数据结构维护,维护的过程都不难,因此普通线段树即可维护。

要注意的点就是,为了找连续区间的长度,我们的操作就是再维护两个数组 \(L,R\) ,在转移时用这两个值来更新 \(val\) 。另外,在询问答案时,从三种情况考虑:

  1. 答案在左区间

  2. 答案在右区间

  3. 答案跨越两个区间

就这样按序扫过来,就能知道最左端的解了。

Code

#include<bits/stdc++.h>
#define N 50005
using namespace std;
int n,m;
struct Seg
{
	int L[N<<2],R[N<<2],val[N<<2];
	int tag[N<<2];
	void push_up(int p,int l,int r)
	{
		int mid=l+r>>1;
		L[p]=L[p<<1],R[p]=R[p<<1|1];
		if(L[p<<1]==mid-l+1) L[p]+=L[p<<1|1];
		if(R[p<<1|1]==r-mid) R[p]+=R[p<<1];
		val[p]=max(R[p<<1]+L[p<<1|1],max(val[p<<1],val[p<<1|1]));
	}
	void build(int p,int l,int r)
	{
		tag[p]=-1;
		if(l==r)
		{
			L[p]=R[p]=val[p]=1;
			return ;
		}
		int mid=l+r>>1;
		build(p<<1,l,mid),build(p<<1|1,mid+1,r);
		push_up(p,l,r);
	}
	void spread(int p,int l,int r)
	{
		if(tag[p]==-1) return ;
		int mid=l+r>>1;
		val[p<<1]=L[p<<1]=R[p<<1]=tag[p]*(mid-l+1);
		val[p<<1|1]=L[p<<1|1]=R[p<<1|1]=tag[p]*(r-mid);
		tag[p<<1]=tag[p<<1|1]=tag[p];
		tag[p]=-1;
	}
	void update(int p,int l,int r,int nl,int nr,int v)
	{
		if(nl<=l&&nr>=r)
		{
			val[p]=L[p]=R[p]=v*(r-l+1),tag[p]=v;
			return ;
		}
		spread(p,l,r);
		int mid=l+r>>1;
		if(nl<=mid) update(p<<1,l,mid,nl,nr,v);
		if(nr>mid) update(p<<1|1,mid+1,r,nl,nr,v);
		push_up(p,l,r);
	}
	int ask(int p,int l,int r,int k)
	{
		if(l==r) return l;
		spread(p,l,r);
		int mid=l+r>>1;
		if(val[p<<1]>=k) return ask(p<<1,l,mid,k);
		if(R[p<<1]+L[p<<1|1]>=k) return mid-R[p<<1]+1;
		if(val[p<<1|1]>=k) return ask(p<<1|1,mid+1,r,k);
	}
}t1;
int main()
{
	scanf("%d%d",&n,&m);
	t1.build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		int op,x,y;
		scanf("%d%d",&op,&x);
		if(op==1)
		{
			if(t1.val[1]<x)
			{
				puts("0");
				continue;
			}
			int pos=t1.ask(1,1,n,x);
			printf("%d\n",pos);
			t1.update(1,1,n,pos,pos+x-1,0);
		}
		else
		{
			scanf("%d",&y);
			t1.update(1,1,n,x,x+y-1,1);
		}
	}
}

标签:return,val,int,Hotel,区间,USACO08FEB,答案,P2894,维护
来源: https://www.cnblogs.com/Freshair-qprt/p/16537766.html