您的位置:首页 > 其它

POJ 3667 Hotel(线段树+区间合并+延迟标记)

2016-08-22 10:14 507 查看
延迟标记很重要,没有延迟标记,时间复杂度还是O(n)。

//
// main.cpp
// Richard
//
// Created by 邵金杰 on 16/8/21.
// Copyright © 2016年 邵金杰. All rights reserved.
//

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=50000+100;
struct node{
int l,r;
int lsum,rsum,sum;
int mark;
int getlen() {return r-l+1;}
void getsum() {lsum=rsum=sum=(mark?0:getlen());}
}tree[maxn*4];
int getmid(int l,int r) {return (l+r)>>1;}
void BuildTree(int p,int l,int r)
{
tree[p].l=l;
tree[p].r=r;
tree[p].mark=0;
tree[p].sum=tree[p].lsum=tree[p].rsum=tree[p].getlen();
if(l==r) return ;
int mid=getmid(l,r);
BuildTree(p*2,l,mid);
BuildTree(p*2+1,mid+1,r);
}
int query(int p,int x)
{
// cout<<p<<endl;
if(tree[p].l==tree[p].r&&x==1)
return tree[p].l;
if(tree[p].mark!=-1)
{
tree[p*2].mark=tree[p*2+1].mark=tree[p].mark;
tree[p].mark=-1;
tree[p*2].getsum();
tree[p*2+1].getsum();
}
if(tree[p*2].sum>=x) return query(p*2,x);
else if(tree[p*2].rsum+tree[p*2+1].lsum>=x) return tree[p*2].r-tree[p*2].rsum+1;
else if(tree[p*2+1].sum>=x) return query(p*2+1,x);
else return 0;
}
void modify(int p,int l,int r,int mark)
{
if(tree[p].l==l&&tree[p].r==r)
{
tree[p].mark=mark;
tree[p].getsum();
return ;
}
if(tree[p].mark!=-1)
{
tree[p*2].mark=tree[p*2+1].mark=tree[p].mark;
tree[p].mark=-1;
tree[p*2].getsum();
tree[p*2+1].getsum();
}
int mid=getmid(tree[p].l,tree[p].r);
if(r<=mid) modify(p*2,l,r,mark);
else if(l>mid) modify(p*2+1,l,r,mark);
else{
modify(p*2,l,mid,mark);
modify(p*2+1,mid+1,r,mark);
}
int temp=max(tree[p*2].sum,tree[p*2+1].sum);
tree[p].sum=max(temp,tree[p*2].rsum+tree[p*2+1].lsum);
tree[p].lsum=tree[p*2].lsum;
tree[p].rsum=tree[p*2+1].rsum;
if(tree[p*2].sum==tree[p*2].getlen()) tree[p].lsum+=tree[p*2+1].lsum;
if(tree[p*2+1].sum==tree[p*2+1].getlen()) tree[p].rsum+=tree[p*2].rsum;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
int cmd,a,b;
BuildTree(1,1,n);
for(int i=0;i<m;i++)
{
scanf("%d",&cmd);
if(cmd==1)
{
scanf("%d",&a);
int p=query(1,a);
printf("%d\n",p);
if(p) modify(1,p,p+a-1,1);
}
else
{
scanf("%d%d",&a,&b);
modify(1,a,a+b-1,0);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: