您的位置:首页 > 其它

poj 1823 Hotel (分段线段树)

2014-02-20 20:45 351 查看
很长时间没写过分段的线段树了,自己开始一看也感觉一头雾水,但是最长的长度分为左最长,最长和右最长这是一开始就必须清楚的,分段更新我也不太熟悉,看了下别人的博客,感觉思路很清晰,敲出来,最后2个数据怎么搞都是错的,整整改了2个小时,最后看着别人的代码一句一句的对着看,终于发现自己看掉了一种情况,记事在左右结点的状态改变后,父节点也需要按条件进行改变。也就是upDate中的

if(node[L(u)].f == node[R(u)].f)

        node[u].f = node[R(u)].f;

#include<cstdio>
#include<cstring>
#include<iostream>
#define L(u) (u<<1)
#define R(u) (u<<1|1)
using namespace std;
const int N = 16010;

struct Node {
int l,r;
int lma, ma, rma, f;
}node[N<<2];

int Max(int a,int b)
{
return a>b?a:b;
}

void pushDown(int u,int c)//往下一层进行更新操作
{
node[u].f = 0;
node[L(u)].f = c;
node[R(u)].f = c;  //左右继续保持原状,便于继续进行更新
if(c == 1)
{
node[L(u)].lma = node[L(u)].ma = node[L(u)].rma = 0;
node[R(u)].lma = node[R(u)].ma = node[R(u)].rma = 0;

}
else
{
node[L(u)].lma = node[L(u)].ma = node[L(u)].rma = node[L(u)].r - node[L(u)].l + 1;
node[R(u)].lma = node[R(u)].ma = node[R(u)].rma = node[R(u)].r - node[R(u)].l + 1;
}

}

void build(int u,int left,int right)
{
node[u].l = left, node[u].r = right;
if(node[u].l==node[u].r)
{
return;
}
int mid = (node[u].l+node[u].r)>>1;
build(L(u),left,mid);
build(R(u),mid+1,right);
}

void upDate(int u,int left,int right,int c)
{
if(left<=node[u].l&&node[u].r<=right)
{
node[u].f = c;
if(c == 1)
{
node[u].lma = node[u].ma = node[u].rma = 0;
}
else
{
node[u].lma = node[u].ma = node[u].rma = node[u].r - node[u].l + 1;
}
return;
}
if(c == node[u].f)
return;

if(-1*c == node[u].f)
{
pushDown(u, node[u].f);
}

int mid = (node[u].l+node[u].r)>>1;

if(right<=mid)
upDate(L(u),left,right,c);
else if(left>mid)
upDate(R(u),left,right,c);
else
{
upDate(L(u),left,mid,c);
upDate(R(u),mid+1,right,c);
}

//这里需要对父节点的信息进行更新
if(node[L(u)].f == -1)
{
node[u].lma = node[L(u)].ma + node[R(u)].lma;
}
else
{
node[u].lma = node[L(u)].lma;
}

if(node[R(u)].f == -1)
{
node[u].rma = node[R(u)].ma + node[L(u)].rma;
}
else
{
node[u].rma = node[R(u)].rma;
}

int a = node[L(u)].rma + node[R(u)].lma;
int b = Max(node[L(u)].ma, node[R(u)].ma);
int g = Max(node[u].lma, node[u].rma);
node[u].ma = Max(Max(a,b),g);

if(node[L(u)].f == node[R(u)].f)
node[u].f = node[R(u)].f;
}

int main(void)
{
int n, m, x, y, z;
scanf("%d%d",&n,&m);
build(1, 1, n);
node[1].f = -1;
node[1].ma = n;
while(m--)
{
scanf("%d",&x);
if(x == 1)
{
scanf("%d%d",&y,&z);
upDate(1, y, y+z-1, 1);
}
else if(x == 2)
{
scanf("%d%d",&y,&z);
upDate(1, y, y+z-1, -1);
}
else
{
cout<<node[1].ma<<endl;
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: