hdu 1540(线段树单点更新 区间合并)
来源:互联网 发布:待机长平板 知乎 编辑:程序博客网 时间:2024/06/05 05:57
解题思路:这一题要求的是连续区间,所以可以把它的子区间合并,这里运用线段树,但是在保存节点信息的方面要做一点修改
lsum:从这个区间的左端点往右能够找到的最大连续区间;
rsum:从这个区间的右端点往左能够找到的最大连续区间;
msum:表示这整个区间能够找到的最大连续区间;
sum:0表示这个区间还没有被破坏的点,大于0表示这个区间已经有被破坏的点。
接下来过程就是从大的区间逐渐分解小区间,然后逼近要求的点。。
这道题我一开始只记录了整个区间能够找到的最大连续区间,但这样就会有一个问题了,因为把[l,r]区间分解为[l,mid],[mid+1,r]区间,很有可能这个mid在最大连续区间里,这样就理所当然的要记录lsum和rsum了。
#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int maxn = 50000;struct Segment{int l,r;int lsum,rsum,msum,sum;//sum表示该线段是否被有点被破坏}tree[maxn<<2];void PushUp(int rt){tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum;if(tree[rt].sum){if(!tree[rt<<1].sum)tree[rt].lsum = tree[rt<<1].msum + tree[rt<<1|1].lsum;else tree[rt].lsum = tree[rt<<1].lsum;if(!tree[rt<<1|1].sum)tree[rt].rsum = tree[rt<<1|1].msum + tree[rt<<1].rsum;else tree[rt].rsum = tree[rt<<1|1].rsum;tree[rt].msum = max(tree[rt<<1].msum,tree[rt<<1|1].msum);tree[rt].msum = max(tree[rt].msum,tree[rt<<1].rsum + tree[rt<<1|1].lsum);}else{tree[rt].lsum = tree[rt].rsum = tree[rt].msum = tree[rt<<1].msum + tree[rt<<1|1].msum;}}void build(int rt,int l,int r){tree[rt].l = l, tree[rt].r = r;tree[rt].lsum = tree[rt].rsum = tree[rt].msum = 1;tree[rt].sum = 0;if(l == r) return;int mid = (l + r) >> 1;build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);PushUp(rt);}void insert(int rt,int t,int val){if(tree[rt].l == tree[rt].r){tree[rt].sum = val;if(tree[rt].sum){tree[rt].lsum = tree[rt].rsum = tree[rt].msum = 0;}else{tree[rt].lsum = tree[rt].rsum = tree[rt].msum = 1;}return;}int mid = (tree[rt].l + tree[rt].r) >> 1;if(t <= mid) insert(rt<<1,t,val);else insert(rt<<1|1,t,val);PushUp(rt);}int query(int rt,int t){if(tree[rt].l == tree[rt].r || !tree[rt].msum || !tree[rt].sum){return tree[rt].msum;}int mid = (tree[rt].l + tree[rt].r) >> 1;if(t <= mid){if(t >= mid - tree[rt<<1].rsum + 1)return tree[rt<<1].rsum + tree[rt<<1|1].lsum;else return query(rt<<1,t);}else{if(mid + tree[rt<<1|1].lsum >= t)return tree[rt<<1].rsum + tree[rt<<1|1].lsum;else return query(rt<<1|1,t);}}int main(){int n,m;char ch;while(cin >> n >> m){getchar();int id,top = 0,stack[maxn];build(1,1,n);while(m--){cin >> ch;if(ch == 'D'){cin >> id;stack[top++] = id;insert(1,id,1);}else if(ch == 'Q'){cin >> id;cout << query(1,id) << endl;}else if(ch == 'R'){id = stack[--top];insert(1,id,0);}}}return 0;}
0 0
- hdu 1540(线段树单点更新 区间合并)
- HDU 1540 Tunnel Warfare(线段树 区间合并 +单点更新)
- hdu 3308 LCIS (线段树+单点更新+区间合并)
- HDU 3308 LCIS(线段树区间合并 单点更新)
- HDU 1540——Tunnel Warfare(线段树,区间合并+单点更新+单点查询)
- HDU 1540 Tunnel Warfare(线段树单点更新+区间合并)
- hdu 1540 Tunnel Warfare(线段树单点更新+区间合并)
- hdu 1540 Tunnel Warfare(线段树——单点更新+区间合并)
- HDU 1540Tunnel Warfare Tunnel Warfare (线段树- 区间合并-单点更新查询)
- hdu 3308 线段树单点更新 区间合并
- hdu.3308 LCIS(线段树,区间合并+单点更新)
- HDU 3308 LCIS 线段树的单点更新,区间合并
- hdu 1540 Tunnel Warfare 线段树 单点更新,查询区间长度,区间合并
- [HDU 5316] Magician (线段树+单点更新+区间询问+区间合并)
- poj2892,线段树单点更新,区间合并
- hdu5316 Magician (线段树+单点更新+区间查询+区间合并)
- hdu 1540 Tunnel Warfare(单点更新,区间合并)
- HDU 1540 Tunnel Warfare(单点更新,区间合并)
- C/C++程序的内存分配方式
- ZeroMQ接口函数之 :zmq_bind - 绑定一个socket
- scrapy setting.py 配置
- MyBatis底层基础和拦截器 - 第一部分
- 字符串以XX开头或结尾
- hdu 1540(线段树单点更新 区间合并)
- sort +awk+uniq 统计文件中出现次数最多的前10个单词
- Leetcode 10. Regular Expression Matching
- VC2010——error C2440 “static_cast” 无法从“void (_thiscall )(void)”转换为“LRESULT
- 分享卫星位置速度和轨道计算 MATLAB
- 了解Bootstrap
- 7_Android动画深入分析
- 五猴分桃
- soledede-Item-Based Recommendation(基于项目的系统过滤推荐)