模板(线段树 + 树状数组 + 单点查询 + 区间查询)eg:HDU 1754
来源:互联网 发布:2017淘宝开店营业执照 编辑:程序博客网 时间:2024/04/30 11:08
HDU 1754 - I Hate It当例题;
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define lson l, m, rt<<1//<<左移运算符#define rson m+1, r, rt<<1|1using namespace std; const int treen = 200000 + 10; int tree[treen << 2];void pushUP(int rt) { //向上更新 tree[rt] = max(tree[rt<<1], tree[rt<<1|1]);}void build(int l, int r, int rt) { if(l == r) {//如果左边=右边边界,说明这个已经是一个点了,比如[1,1]闭区间里只有1个数 scanf("%d", &tree[rt]);//然后更细端点值,我们这里称他为叶子 return; } int m = (l+r)>>1; build(lson);//如果没有到叶子的话,继续往下分,这里称为左儿子 build(rson);//右儿子 pushUP(rt);//吧叶子更新后,上面的节点并没有更新,向上更新}void updata(int p, int add, int l, int r, int rt) { if(l == r) { tree[rt] = add;//在原数基础上加减的话用+=(全部用+=,需要减的话传入的时候变为负的) //更改原数的话,用= return; } int m = (l+r)>>1;//分为一半,二分原理去更新,更快 if(p <= m) updata(p, add, lson);//更新的点在左边 else updata(p, add, rson);//右边 pushUP(rt);//更新后需要向上更新}int query(int L, int R, int l, int r, int rt) { if(L<=l && r<=R) {//查询的区间正好在此区间的内的话,直接返回节点值,也就是要求的和 //(节点放的是下面数的总和) return tree[rt]; } int m = (r+l)>>1;//同上 int ret = 0; if(L <= m) ret = max(query(L, R, lson), ret); if(R > m) ret = max(query(L, R, rson), ret); return ret;//返回最大的值}int main() { int n, m; while(~scanf("%d %d", &n, &m)) { memset(tree, 0, sizeof(tree)); build(1, n, 1);//建树 for(int i = 0; i < m; i++) { char op; int a, b; cin >> op >> a >> b; if(op == 'U') { updata(a, b, 1, n, 1);//更新 }else { printf("%d\n", query(a, b, 1, n, 1));//查询 } } } return 0;}
树状数组 解释
一定要理解之后才看的懂
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std; typedef long long ll; const int maxn = 200000 + 100;; int h[maxn], a[maxn]; int n, m; inline int lowbit(int x) { //给出下一个需要操作数组的下标 return x&(-x);}inline void updata(int x) { while(x <= n) {//x的值是变化的,直到需要更新的更新了 h[x] = a[x]; for(int i = 1; i < lowbit(x); i<<=1) h[x] = max(h[x], h[x-i]); x += lowbit(x); }}int findans(int begin, int end) { int ans = 0; while(end >= begin) { ans = max(ans, a[end]); end--; for(; end-lowbit(end)>=begin; end-=lowbit(end)) ans = max(ans, h[end]); } return ans;}int main() { while(~scanf("%d %d", &n, &m)) { for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); updata(i);//每有一个数值输入就需要更新树状数组 } char ch; int x, y; for(int i = 0; i < m; i++) { cin >> ch >> x >> y; if(ch == 'Q') { printf("%d\n", findans(x, y)); }else if(ch == 'U') { a[x] = y; updata(x);//修改后就需要更新 } } } return 0;}
阅读全文
0 0
- 模板(线段树 + 树状数组 + 单点查询 + 区间查询)eg:HDU 1754
- 模板(线段树 + 树状数组 + 区间修改 + 区间查询)eg:POJ 3468
- [模板]树状数组(区间修改单点查询)
- HDu 1556 Color the ball【线段树&&树状数组】区间更新,单点查询
- 树状数组模板(区间更新单点查询)
- Flowers(树状数组+区间更新+单点查询+区间更新单点查询模板)
- hdu 4533(树状数组区间更新+单点查询)
- HDU 1754 (线段树+单点更新+区间查询)
- hdu1166 树状数组模板:单点更新,区间求和(区间查询)
- NBOJv2 1050 Just Go(线段树/树状数组区间更新单点查询)
- hdu 2642 二维树状数组 单点更新区间查询 模板水题
- hdu 2642二维树状数组 单点更新区间查询 模板题
- HDU 4819 Mosaic(二维线段树区间查询+单点更新模板)
- HDU 4819 Mosaic(二维线段树单点更新+区间查询+自己的写法模板)
- HDU1754线段树单点更新区间查询(数组版)
- hdu 1754 线段树单点修改+区间查询
- [HDU 4031]Attack[树状数组区间更新单点查询]
- hdu 4046 Panda (线段树 单点更新 区间查询)
- 【SSM】Spring+SpringMVC+mybatis入门(环境搭建)
- Python学习之Tkinter
- 《机器学习实战》学习笔记1
- OperationalError: (2006, 'MySQL server has gone away')
- 安装集成PHP开发环境出现“计算机中丢失 MSVCR110.dll”问题
- 模板(线段树 + 树状数组 + 单点查询 + 区间查询)eg:HDU 1754
- poj3020
- NKOJ 3545 接近(DP+单调队列)
- 异常:Caused by:java.net.ConnectException:Connection refused: connect
- 签到第一篇播客
- TLD算法,opencv3,vs2015
- jQuery简单练习(2)
- 二叉排序树
- 翻转单词顺序