【线段树】16pts 求调
查看原帖
【线段树】16pts 求调
481330
sunyizhe还是MC大佬楼主2023/1/2 12:08

代码 #1 #2 AC,其余全WA

//程序算法:线段树 
#include <bits/stdc++.h>
using namespace std;
const int N=50010;
struct Node{
	int l,r,lazy;
	int max,lmax,rmax;
}t[N*4];
void build(int rt,int l,int r)
{
	t[rt].l=l,t[rt].r=r;
	t[rt].max=t[rt].lmax=t[rt].rmax=r-l+1;
	if(l==r)return;
	int mid=(l+r)>>1;
	build(rt*2,l,mid);
	build(rt*2+1,mid+1,r);
}

//该问题存在两种修改:①预定;②退房 
void pushdown(int rt)
{
	if(t[rt].lazy==1)
	{
		t[rt*2].max=t[rt*2].lmax=t[rt*2].rmax=0;
		t[rt*2+1].max=t[rt*2+1].lmax=t[rt*2+1].rmax=0;
		//房间全部被占满。 
		
		t[rt*2].lazy=t[rt*2+1].lazy=1;//下发 
	}
	else if(t[rt].lazy==2)
	{
		t[rt*2].max=t[rt*2].lmax=t[rt*2].rmax=t[rt*2].r-t[rt*2].l+1;
		t[rt*2+1].max=t[rt*2+1].lmax=t[rt*2+1].rmax=t[rt*2+1].r-t[rt*2+1].l+1;
		//房间全部空闲。
		
		t[rt*2].lazy=t[rt*2+1].lazy=2;//下发。 
	}
	t[rt].lazy=0;//清除。 
}

//区间修改。 
void modify(int rt,int l,int r,int v)
{
	if(t[rt].l>=l&&t[rt].r<=r)
	{
		if(v==1)t[rt].max=t[rt].lmax=t[rt].rmax=0;
		else t[rt].max=t[rt].lmax=t[rt].rmax=t[rt].r-t[rt].l+1;
		t[rt].lazy=v;
		return;
	}
	pushdown(rt);
	int mid=(t[rt].l+t[rt].r)>>1;
	if(l<=mid)modify(rt*2,l,r,v);
	if(r>mid)modify(rt*2+1,l,r,v);
	t[rt].max=max(max(t[rt*2].max,t[rt*2+1].max),t[rt*2].rmax+t[rt*2+1].lmax);
	int llen=t[rt*2].r-t[rt*2].l+1,rlen=t[rt*2+1].r-t[rt*2+1].l+1;
	t[rt].lmax=t[rt*2].lmax==llen?llen+t[rt*2+1].lmax:t[rt*2].lmax;
	t[rt].rmax=t[rt*2+1].rmax==rlen?rlen+t[rt*2].rmax:t[rt*2+1].rmax;
}
int query(int rt,int x)//x个房间。 
{
	if(t[rt].max<x)return 0;//无法满足。 
	if(t[rt].r-t[rt].l+1==x)return t[rt].l;
	pushdown(rt);
	
	//优先左边。 
	if(t[rt*2].max>=x)return query(rt*2,x);
	if(t[rt*2].rmax+t[rt*2+1].lmax>=x)return t[rt*2].r-t[rt*2].rmax+1;
	if(t[rt*2+1].max>=x)return query(rt*2+1,x);
}
int n,m;
int main()
{
	cin>>n>>m;
	int cmd,x,y;
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		cin>>cmd>>x;
		if(cmd==1)
		{
			y=query(1,x);
			cout<<y<<endl;
			modify(1,y,y+x-1,1);
		}
		else
		{
			cin>>y;
			modify(1,x,x+y-1,2);
		}
	}
	return 0;
}
2023/1/2 12:08
加载中...