ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P2894 [USACO08FEB]Hotel G

2022-07-31 18:32:16  阅读:129  来源: 互联网

标签:return val int Hotel 区间 USACO08FEB 答案 P2894 维护


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有