HDU1540Tunnel Warfare(线段树区间合并)
2017-03-15 18:33
260 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1540
题目大意:
一条线上的点,D x是破坏这个点,Q x是表示查询以x所在的最长的连续的点的个数,R是恢复上一次破坏的点。
分析:
线段树结点 设置一个 ll 记录区间左端点开始的最大连续个数, rl 记录区间右端点开始的最大的连续个数,ml表示该区间最大的连续点的个数。主要是更新和查询两个操作。
收获:
掌握区间合并的方式。
题目大意:
一条线上的点,D x是破坏这个点,Q x是表示查询以x所在的最长的连续的点的个数,R是恢复上一次破坏的点。
分析:
线段树结点 设置一个 ll 记录区间左端点开始的最大连续个数, rl 记录区间右端点开始的最大的连续个数,ml表示该区间最大的连续点的个数。主要是更新和查询两个操作。
收获:
掌握区间合并的方式。
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> using namespace std; const int maxn = 50005; struct Node { int l, r; int ll, rl, ml; }segTree[maxn<<2]; void Build(int rt, int l, int r) { segTree[rt].l = l; segTree[rt].r = r; segTree[rt].ll = segTree[rt].rl = segTree[rt].ml = r - l + 1; if(l == r) return ; int mid = (l + r) >> 1; Build(rt<<1, l, mid); Build((rt<<1)|1, mid+1, r); } void update(int rt, int t, int val) { if(segTree[rt].l == segTree[rt].r) { if(val == 1) segTree[rt].ll = segTree[rt].rl = segTree[rt].ml = 1; else segTree[rt].ll = segTree[rt].rl = segTree[rt].ml = 0; return ; } int mid = (segTree[rt].l + segTree[rt].r) >> 1; if(t <= mid) update(rt<<1, t, val); else update((rt<<1)|1, t, val); segTree[rt].ll = segTree[rt<<1].ll; segTree[rt].rl = segTree[(rt<<1)|1].rl; segTree[rt].ml = max(segTree[rt<<1].ml, segTree[(rt<<1)|1].ml); segTree[rt].ml = max(segTree[rt].ml, segTree[rt<<1].rl + segTree[(rt<<1)|1].ll); if(segTree[rt<<1].ll == segTree[rt<<1].r - segTree[rt<<1].l + 1) segTree[rt].ll += segTree[(rt<<1)|1].ll; if(segTree[(rt<<1)|1].rl == segTree[(rt<<1)|1].r - segTree[(rt<<1)|1].l + 1) segTree[rt].rl += segTree[rt<<1].rl; } int query(int rt, int t) { if(segTree[rt].l == segTree[rt].r || segTree[rt].ml == 0 || segTree[rt].ml == segTree[rt].r - segTree[rt].l + 1) { return segTree[rt].ml; } int mid = (segTree[rt].l + segTree[rt].r) >> 1; if(t <= mid) { if(t >= segTree[rt<<1].r - segTree[rt<<1].rl + 1) return segTree[rt<<1].rl + query((rt<<1)|1, mid+1); //return query(rt<<1, t) + query((rt<<1)|1, mid+1); else return query(rt<<1, t); } else { if(t <= segTree[(rt<<1)|1].l + segTree[(rt<<1)|1].ll - 1) return segTree[(rt<<1)|1].ll + query(rt<<1, mid); //return query((rt<<1)|1, t) + query(rt<<1, mid); else return query((rt<<1)|1, t); } } int que[maxn]; int top; int main() { int n, m, x; char str[10]; while(scanf("%d%d", &n, &m) != EOF) { top = 0; Build(1, 1, n); while(m--) { scanf("%s", str); if(str[0] == 'D') { scanf("%d", &x); que[top++] = x; update(1, x, 0); } else if(str[0] == 'Q') { scanf("%d", &x); printf("%d\n", query(1, x)); } else { if(x > 0) { x = que[--top]; update(1, x, 1); } } } } return 0; }
相关文章推荐
- POJ 3667(线段树,区间合并,成段更新)
- 【bzoj4811】[Ynoi2017]由乃的OJ 树链剖分+线段树区间合并
- 线段树 (区间合并)
- POJ 3667 Hotel ( 线段树区间合并 )
- 多校第三场 1001 hdu 5316 Magician( 区间合并线段树)
- PKU 3667 Hotel (线段树,区间合并,最长连续区间)
- hdu 5316 Magician(线段树区间合并)
- 线段树 区间合并
- uva11235 Frequent values(线段树区间合并)
- 线段树进阶学习(例题)--树状数组学习+离散化+成端更新+区间合并+扫描线
- hdu1540(线段树区间合并)
- 九度OJ 题目1496:数列区间 (线段树 区间合并 +成段更新)
- hdu 3397 Sequence operation 线段树 区间更新 区间合并
- 约会安排 - HDU 4553 - 线段树 - 区间合并
- POJ 3667 Hotel & HDU 2871 Memory Control 线段树区间合并
- 线段树—区间合并
- LCIS --线段树区间合并
- HDU 1540 Tunnel Warfare(线段树区间合并)
- HDOJ 题目3397 Sequence operation(线段树区间覆盖异或合并)
- HDU 3308 (线段树区间合并)