【poj 3667】Hotel 题意&&题解&&代码(C++)

来源:互联网 发布:js设置radio选中 编辑:程序博客网 时间:2024/04/29 17:19

题目链接:
http://poj.org/problem?id=3667
题意:
有n个房间,m个询问,询问的第一个数字若为1,输入一个k,表示寻找一段长度为k的连续空房间,若能找到,则输出满足条件的整段房间里,编号最小的房间的编号,并将这k间空房占满,第一个数字若为2,则输入两个数 x,y,表示将区间x~y的房间全部清空成空房间。
题解:
线段树的每个节点存四个信息:
1 . tr[id].L :表示id所代表的区间中,以最左端开头的最长连续空房间的长度。
2.tr[id].R:表示id所代表的区间中,以最右端结尾的最长连续空房间的长度。
3.tr[id].M:表示id所代表的区间中,最长连续空房间的长度。
4.tr[id].lazy:线段树区间操作时常用信息。。。
具体维护信息的方法与查询方法看代码:
代码:

#include<iostream>#include<algorithm>#include<stdio.h>#define lson (id*2)#define rson (id*2+1)using namespace std;struct node{    int L;int R;int M;int lazy;}tr[300005];void pushup(int id,int l,int r){    int mid=(l+r)/2;    tr[id].M=max(max(tr[lson].M,tr[rson].M),tr[lson].R+tr[rson].L);    if (tr[lson].L==mid-l+1)    tr[id].L=tr[lson].L+tr[rson].L;    else tr[id].L=tr[lson].L;    if (tr[rson].R==r-mid)      tr[id].R=tr[lson].R+tr[rson].R;     else tr[id].R=tr[rson].R;}void pushdown(int id,int l,int r){    if (tr[id].lazy!=-1)    {        int mid=(l+r)/2;        tr[lson].R=tr[lson].L=tr[lson].M=tr[id].lazy*(mid-l+1);             tr[rson].R=tr[rson].L=tr[rson].M=tr[id].lazy*(r-mid);        tr[lson].lazy=tr[rson].lazy=tr[id].lazy;        tr[id].lazy=-1;    }}void build(int id,int l,int r){    tr[id].lazy=-1;    if (l>r) return ;    if (l==r)     {        tr[id].L=1;        tr[id].R=1;        tr[id].M=1;        return ;    }    int mid=(l+r)/2;    build(lson,l,mid);    build(rson,mid+1,r);    pushup(id,l,r);}void exc(int id,int l,int r,int L,int R,int v){    if (l>r || l>R || r<L) return ;    if (l>=L && r<=R)     {        tr[id].L=v*(r-l+1);        tr[id].R=v*(r-l+1);        tr[id].M=v*(r-l+1);        tr[id].lazy=v;        return ;    }    int mid=(l+r)/2;    pushdown(id,l,r);    if (L<=mid) exc(lson,l,mid,L,R,v);    if (R>=mid+1) exc(rson,mid+1,r,L,R,v);    pushup(id,l,r);}int query(int id,int l,int r,int k){    int mid=(l+r)/2;    pushdown(id,l,r);    if (tr[id].M<k)     return 0;    else if (tr[id].L>=k)     return l;    else if (tr[lson].M>=k)    return query(lson,l,mid,k);    else    if (tr[lson].R+tr[rson].L>=k)    return mid-tr[lson].R+1;    else    return query(rson,mid+1,r,k);    return 0;}int n,m,p,x,y;int main(){    scanf("%d%d",&n,&m);    build(1,1,n);    for (int i=1;i<=m;i++)    {        scanf("%d",&p);        if (p==1)        {            scanf("%d",&x);            int ans=query(1,1,n,x);            if (ans!=0) exc(1,1,n,ans,ans+x-1,0);            printf("%d\n",ans);        }        else         {            scanf("%d%d",&x,&y);            exc(1,1,n,x,x+y-1,1);        }       }}
0 0
原创粉丝点击