poj 3667 Hotel

线段树之区间合并。有一个线段。从1到n,以下m个操作,操作分两个类型,以1开头的是查询操作,以2开头的是更新操作

1 w  表示在总区间内查询一个长度为w的可用区间,而且要最靠左,能找到的话返回这个区间的左端点并占用了这个区间。找不到返回0 

接近2个月没怎么学算法刷题了,也落下了非常多东西,慢慢补吧,明天開始二维线段树

#include<iostream>
#define maxn 50010
using namespace std;
int n,m,a,b;
int cmd;
struct stu
{
	int r,l;
	int flag;
	int tlen,llen,rlen;
	int up()
	{
		tlen=llen=rlen=(flag?

0:r-l+1); } }; stu mapp[maxn*4]; void build(int l,int r,int count) { mapp[count].l=l; mapp[count].r=r; mapp[count].tlen=mapp[count].llen=mapp[count].rlen=r-1+1; mapp[count].flag=0; if(l==r) return; int mid=(l+r)/2; build(l,mid,count*2); build(mid+1,r,count*2+1); } void push(int count,int x) { if(mapp[count].flag!=-1) { mapp[count*2].flag=mapp[count*2+1].flag=mapp[count].flag; mapp[count].flag=-1; mapp[count*2].up(); mapp[count*2+1].up(); } } int que(int l,int r,int count) { //if(mapp[count].l==mapp[count].r&&mapp[count].tlen) return mapp[count].l; push(count,r-l+1); if(mapp[count*2].tlen>=a) return que(l,r,count*2); else if(mapp[count*2].rlen+mapp[count*2+1].llen>=a) { return mapp[count*2].r-mapp[count*2].rlen+1; } else if(mapp[count*2+1].tlen>=a) return que(l,r,count*2+1); else return 0; } void updata(int l,int r,int v,int count) { if(mapp[count].l==l&&mapp[count].r==r) { mapp[count].flag=v; mapp[count].up(); return; } push(count,r-l+1); int mid=(mapp[count].l+mapp[count].r)/2; if(r<=mid) updata(l,r,v,count*2); else if(l>=mid+1) updata(l,r,v,count*2+1); else { updata(l,mid,v,count*2); updata(mid+1,r,v,count*2+1); } int tmp=max(mapp[count*2].tlen,mapp[count*2+1].tlen); mapp[count].tlen=max(tmp,mapp[count*2].rlen+mapp[count*2+1].llen); mapp[count].llen=mapp[count*2].llen; mapp[count].rlen=mapp[count*2+1].rlen; if(mapp[count*2].tlen==(mapp[count*2].r-mapp[count*2].l+1)) { mapp[count].llen+=mapp[count*2+1].llen; } if(mapp[count*2+1].tlen==(mapp[count*2+1].r-mapp[count*2+1].l+1)) { mapp[count].rlen+=mapp[count*2].rlen; } } int main() { cin.sync_with_stdio(false); while(cin>>n>>m) { build(1,n,1); for(int i=0;i<m;i++) { cin>>cmd; if(cmd==1) { cin>>a; int ans=que(1,n,1); cout<<ans<<endl; if(ans) updata(ans,ans+a-1,1,1); } else { cin>>a>>b; updata(a,a+b-1,0,1); } } } return 0; }





posted on 2017-06-01 08:56  yjbjingcha  阅读(104)  评论(0编辑  收藏  举报

导航