线段树--单点更新
2016-05-24 16:42
351 查看
按点build线段树,用于求区间的和或者区间最大值。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 55555; int sum[maxn*4]; void PushUp(int rt) { sum[rt] = sum[rt*2] + sum[rt*2+1];//求区间和 sum[rt] = max(sum[rt*2],sum[rt*2+1]);//求区间最大值 } void build(int l, int r, int rt)//建立线段树 { if (l == r) { scanf("%d", &sum[rt]); return; } int m = (l + r) / 2; build(l, m, rt*2); build(m + 1, r, rt*2+1); PushUp(rt); } void update(int p, int add, int l, int r, int rt) { if (l == r) { sum[rt] += add; return; } int m = (l + r) / 2; if (p <= m) update(p, add, l, m, rt*2); else update(p, add, m + 1, r, rt*2+1); PushUp(rt); } int query(int ll, int rr, int l, int r, int rt)//查询线段树 { if (ll <= l && rr >= r) return sum[rt]; int m = (l + r) / 2; int ans = 0; if (ll <= m) ans += query(ll, rr, l, m, rt*2); if (rr > m) ans += query(ll, rr, m + 1, r, rt*2+1); return ans; } int main(void) { int t, c; char d[10]; scanf("%d", &t); for (c = 1; c <= t; c++) { printf("Case %d:\n", c); int n; scanf("%d", &n); build(1, n, 1); while (scanf("%s", d) != EOF) { if (d[0] == 'E') break; int x, y; scanf("%d%d", &x, &y); if (d[0] == 'Q') { int ans = query(x, y, 1, n, 1); printf("%d\n", ans); } if (d[0] == 'S') update(x, -y, 1, n, 1); if (d[0] == 'A') update(x, y, 1, n, 1); } } return 0; }
相关文章推荐
- scala编译的class字节码实现
- FFprobe使用指南
- 单链表实现多项式的相乘-c语言
- android开发环境搭建
- HBase Compaction流程
- 变态跳台阶,最终导向HDU_5698_瞬间移动
- VMware12+Ubuntu16.04 安装 以及全屏的实现
- GCD基础
- 1.处理屏幕触摸(单点触摸)
- 视图添加移动手势
- jQuery前端开发35个小技巧
- ZOJ-1610 Count the Colors
- centos7安装docker
- POJ 1251
- [文摘20160524]为什么你的孩子不像德国孩子那样自律?看过这个就知道怎么做了!
- iOS常识名词解释 2016/04/05
- tabBar的图标不被系统渲染
- Clang Format
- C++ 值传递、指针传递、引用传递
- mysql 修改data目录后 无法使用脚本启动 推荐