POJ 3468 A Simple Problem with Integers (线段树区间更新)
2015-10-19 19:17
489 查看
题目链接:
戳我题目大意:
一组数,从 1 到 n,有两个操作,Q a b -->询问 a 到 b的这个区间的和
C a b c --->让a 到 b这个区间的每个数都加上 c
样例解释:
略解题思路:
自然线段树区间更新了。今天复习一下区间更新。。。//Author LJH //www.cnblogs.com/tenlee #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <map> #define clc(a, b) memset(a, b, sizeof(a)) #define LL long long using namespace std; const int inf = 0x3f; const int INF = 0x3f3f3f3f; const int maxn = 1e5+5; struct Node { int l, r; LL sum, add; }tree[maxn * 6]; void Build(int i, int l, int r); void Update(int i, int l, int r, int val); void PushDown(int i); LL Query(int i, int l, int r); int main() { int n, q; int a, b, c; char op; while(~scanf("%d %d", &n, &q)) { Build(1, 1, n); while(q--) { scanf(" %c", &op); if(op == 'Q') { scanf("%d %d", &a, &b); printf("%lld\n", Query(1, a, b)); } else { scanf("%d %d %d", &a, &b, &c); Update(1, a, b, c); } } } return 0; } void Build(int i, int l, int r) { tree[i].l = l; tree[i].r = r; tree[i].add = 0; if(l == r) { scanf("%lld", &tree[i].sum); return; } int mid = (l + r) >> 1; Build(i << 1, l, mid); Build(i << 1 | 1, mid + 1, r); tree[i].sum = tree[i<<1].sum + tree[i<<1|1].sum; } void Update(int i, int l, int r, int val) { if(tree[i].l == l && tree[i].r == r) //刚好满足时,就标记了 { tree[i].add += val; return; } tree[i].sum += (r - l + 1) * val; //注意此处是 r - l + 1, 而不是 tree[i].r - tree[i].l + 1 int mid = (tree[i].l + tree[i].r) >> 1; if(r <= mid) { Update(i<<1, l, r, val); } else if(l > mid) { Update(i<<1|1, l, r, val); } else { Update(i<<1, l, mid, val); Update(i<<1|1, mid+1, r, val); } } void PushDown(int i) { tree[i<<1|1].add += tree[i].add; tree[i<<1].add += tree[i].add; tree[i].sum += (tree[i].r - tree[i].l + 1) * tree[i].add; tree[i].add = 0; //重置为0 } LL Query(int i, int l, int r) { if(tree[i].add != 0) // 向下更新 { PushDown(i); } if(tree[i].l == l && tree[i].r == r) { return tree[i].sum; } int mid = (tree[i].l + tree[i].r) >> 1; if(r <= mid) { return Query(i<<1, l, r); } else if(l > mid) { return Query(i<<1|1, l, r); } else { return (Query(i<<1, l, mid) + Query(i<<1|1, mid+1, r)); } }
相关文章推荐
- Dojo -- Getting Started篇之Hello Dojo!
- 函数类型,函数名是函数指针吗,函数的强制类型转换
- 151017总结-学军
- 单元测试过程
- JS实现文本框和文本域获取焦点focus()时,光标在本文的末尾
- html的<!DOCTYPE>标签初窥
- 三角形 算法第一集
- winrar在右键菜单上加上:打包自动加上日期时间标签【图文教程】 - imsoft.cnblogs
- MySQL查询优化之explain的深入解析
- python+Eclipse+pydev环境搭建
- linux算术运算小结
- UI19_单例
- 最长公共子串序列一之 两个字符串的最长公共子串
- 判断是否为奇数时:除以2余数等于1.(充分而不必要)
- NSString NSArray NSDictionry属性 用Copy修饰
- 登录的意义
- JAVA - 多线程 - 生产者与消费者
- [leetcode-295]Find Median from Data Stream(java)
- OpenCV之基础轮廓查找
- 河南科技学院CSDN高校俱乐部——2015-2016学年招新总结