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;
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; }
相关文章推荐
- poj 1823 Hotel 线段树,注意懒惰标记,不标记就会超时滴
- POJ 3667 & 1823 Hotel (线段树区间合并)
- 【转】poj 1823 :Hotel (线段树)
- poj 1823 hotel 线段树
- POJ 1823 Hotel 线段树
- POJ 1823 Hotel【线段树】
- poj 1823 hotel(线段树)
- poj 1823 Hotel(线段树,整段更新)
- POJ 1823 Hotel 线段树
- 【转】poj 1823 hotel 线段树【Good】
- poj 1823 Hotel 线段树
- POJ 3667 & 1823 Hotel (线段树区间合并)
- poj 1823 Hotel(数据结构:线段树--区间更新)
- POJ 1823 Hotel 线段树
- POJ 3667 & 1823 Hotel (线段树区间合并)
- [POJ 1823] Hotel 线段树区间合并
- POJ 1823 Hotel(线段树区间更新)
- Poj 1823 Hotel (线段树 区间合并 成段更新)
- [转]poj 1823 Hotel 线段树
- POJ 1823 Hotel(线段树)