poj 1823 酒店管理

来源:互联网 发布:网络共享中心打不开 编辑:程序博客网 时间:2024/03/29 18:06

http://blog.csdn.net/wmn_wmn/article/details/8092052

单纯的线段树经典题目

关键在于如何设计线段树的插入和删除操作

int flag 三个值 0, 1, 2应该是分别表示完全无覆盖, 部分覆盖, 完全覆盖

结点定义中包含 llen 左起最大长度, rlen 右起最大长度, mlen段内最大长度

根据孩子结点情况更新当前结点

void update(int pos)//核心部分 {if(!tt[pos*2].flag)tt[pos].llen = tt[pos*2].mlen + tt[pos*2+1].llen;elsett[pos].llen = tt[pos*2].llen;if(!tt[pos*2+1].flag)tt[pos].rlen = tt[pos*2].rlen + tt[pos*2+1].mlen;elsett[pos].rlen = tt[pos*2+1].rlen;int max1 = max(tt[pos].llen,tt[pos].rlen);int max2 = tt[pos*2].rlen + tt[pos*2+1].llen;int max3 = max(tt[pos*2].mlen,tt[pos*2+1].mlen);tt[pos].mlen = max(max1,max(max2,max3));if(tt[pos*2].flag == tt[pos*2+1].flag) //这里更新flag操作?tt[pos].flag = tt[pos*2].flag;}void insert(int lp,int rp,int pos){if(tt[pos].lp == lp && tt[pos].rp == rp){    tt[pos].flag = 2;tt[pos].llen = tt[pos].rlen = tt[pos].mlen = 0;return;}if(!tt[pos].flag){    tt[pos].flag = 1;tt[pos*2].flag = tt[pos*2+1].flag = 0;tt[pos*2].llen = tt[pos*2].rlen = tt[pos*2].mlen = tt[pos*2].rp - tt[pos*2].lp + 1;tt[pos*2+1].llen = tt[pos*2+1].rlen = tt[pos*2+1].mlen = tt[pos*2+1].rp - tt[pos*2+1].lp + 1;}int mmid = tt[pos].getmid();if(rp <= mmid){    insert(lp,rp,pos*2);}else if(lp > mmid){    insert(lp,rp,pos*2+1);}else{   insert(lp,mmid,pos*2);   insert(mmid+1,rp,pos*2+1);}update(pos);}void rem(int lp,int rp,int pos){if(tt[pos].lp == lp && tt[pos].rp == rp){    tt[pos].flag = 0;tt[pos].llen = tt[pos].rlen = tt[pos].mlen = tt[pos].rp - tt[pos].lp + 1;return;}if(tt[pos].flag == 2){    tt[pos].flag = 1;tt[pos*2].flag = tt[pos*2+1].flag = 2;tt[pos*2].llen = tt[pos*2].rlen = tt[pos*2].mlen = 0;tt[pos*2+1].llen = tt[pos*2+1].rlen = tt[pos*2+1].mlen = 0;}int mmid = tt[pos].getmid();if(rp <= mmid)rem(lp,rp,pos*2);else if(lp > mmid)rem(lp,rp,pos*2+1);else{    rem(lp,mmid,pos*2);rem(mmid+1,rp,pos*2+1);}update(pos);}