HDU 1540 Tunnel Warfare(线段树区间合并)
来源:互联网 发布:中国网络小说家排行榜 编辑:程序博客网 时间:2024/05/21 09:37
题意:
题目定义了3种操作
D代表破坏村庄,
R代表修复最后被破坏的那个村庄,
Q代表询问包括x在内的最大连续区间是多少
思路:
和前面几道线段树的区间合并一样,在线段树的区间内,我们要用三个变量记录左边连续区间,右边连续区间和最大连续区间。
这题主要的难点是怎么查询。
我的查询函数是这么写的。
int query(int o, int L, int R, int pos) { if(L == R) return 0; int M = MID; pushDown(o, L, R); if(M - mxR[ls] + 1 <= pos && pos <= M + mxL[rs]) return mxR[ls] + mxL[rs]; else if(pos <= M) return query(lson, pos); else return query(rson, pos);}
判断当前的位置是否满足在左边连续和右边连续的区间之内。
如果满足返回当前该区间的长度,否则向下查找。
#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#define MID (L + R) >> 1#define ls (o<<1)#define rs (o<<1|1)#define lson ls, L, M#define rson rs, M+1, R#define LEN(L, R) ((R) - (L) + 1)using namespace std;const int N = (int)5e4 + 10;int n, m;int mxL[N<<2], mxR[N<<2], mx[N<<2], cov[N<<2];vector<int> vec;int max(int a, int b, int c) { return max(a, max(b, c));}void pushUp(int o, int L, int R) { int M = MID; mxL[o] = mxL[ls], mxR[o] = mxR[rs]; mx[o] = max(mx[ls], mx[rs], mxR[ls] + mxL[rs]); if(mxL[ls] == LEN(L, M)) mxL[o] += mxL[rs]; if(mxR[rs] == LEN(M+1, R)) mxR[o] += mxR[ls]; if(cov[ls] == cov[rs]) cov[o] = cov[ls]; else cov[o] = -1;}void pushDown(int o, int L, int R) { if(cov[o] != -1) { int M = MID; cov[ls] = cov[rs] = cov[o]; mxL[ls] = mxR[ls] = mx[ls] = cov[o] * LEN(L, M); mxL[rs] = mxR[rs] = mx[rs] = cov[o] * LEN(M+1, R); cov[o] = -1; }}void build(int o, int L, int R) { cov[o] = -1; if(L == R) { mxL[o] = mxR[o] = mx[o] = cov[o] = 1; return ; } int M = MID; build(lson); build(rson); pushUp(o, L, R);}void modify(int o, int L, int R, int pos, int val) { if(L == R) { mxL[o] = mxR[o] = mx[o] = cov[o] = val; return ; } int M = MID; pushDown(o, L, R); if(pos <= M) modify(lson, pos, val); else modify(rson, pos, val); pushUp(o, L, R);}int query(int o, int L, int R, int pos) { if(L == R) return 0; int M = MID; pushDown(o, L, R); if(M - mxR[ls] + 1 <= pos && pos <= M + mxL[rs]) return mxR[ls] + mxL[rs]; else if(pos <= M) return query(lson, pos); else return query(rson, pos);}int main() { char op[10]; int ql, qr, x; while(~scanf("%d%d", &n, &m)) { build(1, 1, n); vec.clear(); while(m--) { scanf("%s", op); if(op[0] == 'D') { scanf("%d", &x); vec.push_back(x); modify(1, 1, n, x, 0); }else if(op[0] == 'Q') { scanf("%d", &x); int ans = query(1, 1, n, x); printf("%d\n", ans); }else if(op[0] == 'R') { x = vec.back(); vec.pop_back(); modify(1, 1, n, x, 1); } } } return 0;}
0 0
- 【Hdu】1540 Tunnel Warfare(线段树|区间合并)
- HDU 1540 Tunnel Warfare(线段树区间合并)
- HDU 1540 Tunnel Warfare (线段树区间合并)
- hdu 1540 Tunnel Warfare (线段树区间合并)
- HDU 1540 Tunnel Warfare (线段树,区间合并)
- HDU-1540 Tunnel Warfare (线段树区间合并)
- HDU 1540Tunnel Warfare Tunnel Warfare (线段树- 区间合并-单点更新查询)
- HDU-1540 Tunnel Warfare 线段树 区间合并
- hdu 1540 Tunnel Warfare(线段树区间合并)
- hdu 1540 & poj 2892 Tunnel Warfare 线段树区间合并
- HDU 1540 Tunnel Warfare(线段树 区间合并 +单点更新)
- hdu 1540/POJ 2892 Tunnel Warfare 【线段树区间合并】
- HDU - 1540 Tunnel Warfare(线段树 区间合并)
- hdu 1540 Tunnel Warfare 【线段树 区间合并】
- HDU 1540 Tunnel Warfare 线段树区间合并
- HDU 1540 Tunnel Warfare(线段树区间合并)
- Hdu 1540 Tunnel Warfare【线段树区间合并学习】
- HDU 1540 Tunnel Warfare 线段树区间合并
- 公司章程约定股东董事离任后的竞业禁止是否有效
- Android 屏幕适配之代码适配
- java servlet 监听器种类及介绍
- 架构设计:负载均衡层设计方案(3)——Nginx进阶
- 数据存储详解(一)---->SharedPreferences(xml存储)
- HDU 1540 Tunnel Warfare(线段树区间合并)
- server.xml详解
- 黑马程序员--多态
- flex两种方式画出一个动态时钟
- Java中静态变量的适用场景
- cocos2d-x v2 升级到 v3
- 从超算谈起
- ReactiveCocoa基本组件:深入浅出RACCommand
- MBProgressHUD的使用