HDU 1540 Tunnel Warfare(线段树区间合并)
2015-09-07 11:24
435 查看
题意:
题目定义了3种操作D代表破坏村庄,
R代表修复最后被破坏的那个村庄,
Q代表询问包括x在内的最大连续区间是多少
思路:
和前面几道线段树的区间合并一样,在线段树的区间内,我们要用三个变量记录左边连续区间,右边连续区间和最大连续区间。这题主要的难点是怎么查询。
我的查询函数是这么写的。
[code]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); }
判断当前的位置是否满足在左边连续和右边连续的区间之内。
如果满足返回当前该区间的长度,否则向下查找。
mymy codecode
[code]#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; }
相关文章推荐
- java servlet 监听器种类及介绍
- 数据存储详解(一)---->SharedPreferences(xml存储)
- Android 屏幕适配之代码适配
- JS实现一键复制功能
- 指针变量作为函数参数使用时注意的问题!
- PHP_CURL之模拟POST登陆
- 公司章程约定股东董事离任后的竞业禁止是否有效
- count和count_if函数
- labview 安装提示windows installer 引擎错误问题
- Fragment Activity之间的通信方法之一
- UNIGUI:How to redirect and close session?
- C#学习笔记--详解委托,事件与回调函数
- Linux命令行下统计当前文件夹下的文件个数
- Netty框架启动详解
- Android 安装调试出错:Installation error: INSTALL_FAILED_MEDIA_UNAVAILABLE
- java解压缩文件
- 封装好的Android广告栏,效果较好功能强大,可以很方便地直接使用
- android开发中WebView控件的实例与注意要点——个人主页浏览器简易实现
- jsp页面遍历
- MSSql Server基础学习系列———聚合函数