HDU1540--线段树(最长连续区间)
来源:互联网 发布:java float与double 编辑:程序博客网 时间:2024/05/21 18:43
这个题目好像不是很难,可是我想了很久,还超时了。。我用的是普通线段树和二分,第一次用二分超时啊啊啊啊啊
好,让我们言归正传。(参考别的大佬的做法,贼6)
看到这个题目之后,能够想到它是为了求包含一个点的最大连续区间。那么多的区间,应该是要用线段树来做。
可以想得到,查询的时候,是从这个点展开,判断左右是否连续。
首先,我们用递归查询到这个点,或者说是包含这个点的连续区间,假设它是一个左子树,那我们就要加上它相邻的右子树的从左边开始的连续区间,如果它是右子树,那么就按相反。
这样的话,我们不如就建立两个数组,一个是从左边开始累加区间长度的数组(lsum[]),一个是从右边开始累加区间长度的数组(rsum[]),然后建树,更新节点,查询。
还要提一点,由于题目中有一个什么重建,emmm,就是先进后出的栈嘛,所以我们这里就可以用到c++中的一个stack容器。
有这几个常用的操作吧:
stack<int> s;
1.入栈:如s.push(x);
2.出栈:如 s.pop().注意:出栈操作只是删除栈顶的元素,并不返回该元素。
3.访问栈顶:如s.top();
4.判断栈空:如s.empty().当栈空时返回true。
5.访问栈中的元素个数,如s.size();
贴代码:
#include"cstdio"#include"stack"using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define maxn 50010int lsum[4*maxn],rsum[4*maxn],flag;void Build(int l,int r,int rt) { lsum[rt] = rsum[rt] = r-l+1; if (l == r) return; int m = (l+r) >> 1; Build(lson); Build(rson);}void Pushup(int rt,int m) { lsum[rt] = lsum[rt<<1]; rsum[rt] = rsum[rt<<1|1]; if (lsum[rt] == m - (m>>1)) lsum[rt] += lsum[rt<<1|1];//yi cuo if (rsum[rt] == m>>1) rsum[rt] += rsum[rt<<1];}void Updata(int p,int x,int l,int r,int rt) { if (l == r) { lsum[rt] = rsum[rt] = x; return; } int m = (l+r) >> 1; if (p <= m) Updata(p,x,lson); else Updata(p,x,rson); Pushup(rt,r-l+1);}int Query(int p,int l,int r,int rt) { if (rsum[rt] >= r-p+1) { flag = 1; return rsum[rt]; } if (lsum[rt] >= p-l+1) { flag = 1; return lsum[rt]; } if (l == r) return 0; int m = (l+r) >> 1, t = 0; if (p > m) { t = Query(p,rson); if (flag) { flag = 0; t += rsum[rt<<1]; } } else { t = Query(p,lson); if (flag) { flag = 0; t += lsum[rt<<1|1]; } } return t;}int main() { int n,m;// freopen("1.in","r",stdin); while(~scanf("%d%d",&n,&m)) { Build(1,n,1); char cmd[2]; stack<int> sta; for (int i = 0;i < m;i ++) { scanf("%s",cmd); if (cmd[0] == 'D') { int x; scanf("%d",&x); sta.push(x); Updata(sta.top(),0,1,n,1); } else if (cmd[0] == 'Q') { int x; flag = 0; scanf("%d",&x); printf("%d\n",Query(x,1,n,1)); } else { Updata(sta.top(),1,1,n,1); sta.pop(); } } } return 0;}
阅读全文
0 0
- HDU1540--线段树(最长连续区间)
- hdu1540(线段树求连续区间最大和)
- hdu1540 线段树之区间左右连续询问
- hdu1540(线段树区间合并)
- hdu1540 线段树区间合并
- hdu1540线段树区间合并
- hdu1540(线段树区间合并)
- hdu1540(线段树)
- hdu1540 Tunnel Warfare(线段树区间合并详解)
- HDU1540-Tunnel Warfare(线段树区间合并)
- poj 2892 hdu1540 线段树 求过某点的最大连续区间。
- HDU1540:Tunnel Warfare(线段树区间合并)
- hdu1540 Tunnel Warfare 线段树区间合并
- HDU1540-Tunnel Warfare-线段树区间合并
- hdu1540 Tunnel Warfare 线段树区间合并
- HDU1540 Tunnel Warfare (线段树区间合并)
- hdu1540-Tunnel Warfare 线段树区间合并
- HDU1540 Tunnel Warfare(线段树,区间合并)
- 排序算法之插入排序
- WEB前端 -- 浮动
- 获取指定进程被启动的次数
- 4用于cifar10的卷积神经网络-4.19tanh和softsign激活函数的输出汇总分析
- Zookeeper安装
- HDU1540--线段树(最长连续区间)
- 11.27学习心得
- 表单提交前验证实现方法
- 你也许要付出5000亿刀的学费,才能明白架构的重要性
- Python实现PAT 1063. Set Similarity (25)
- python学习之头文件问题
- 使用Gradle创建Java项目
- java编程思想---第三章(操作符)
- Gearman的Worker的多进程实现