POJ
来源:互联网 发布:手机淘宝网银怎么开通 编辑:程序博客网 时间:2024/06/07 23:28
题目链接:
题目大意:
数据范围:
解题思路:
if(L <= tree[rt].l && tree[rt].r <= R) { tree[rt].sum += (LL)(tree[rt].r - tree[rt].l + 1) * val; lazy[rt] += (LL)val; return ;}
如果不完全包含,则将lazy标记下放到左右儿子上,即push_down操作,并将当前节点的lazy标记清零。
AC代码:
//线段树--区间修改(Lazy标记),区间求和#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <algorithm>#include <set>#include <map>#include <queue>using namespace std;typedef long long LL;const int inf = 1 << 30;const LL INF = 1LL << 60;const int MaxN = 100010;//这里MaxN = 100000死活过不了!!!int n, q;LL a[MaxN + 5];struct segtree{ LL l, r; LL sum;}tree[4 * MaxN + 5];LL lazy[4 * MaxN + 5];//lazy[i]表示i节点所管辖的区间应该加的值void push_up(LL rt) { tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum;}void push_down(LL rt) { //理解了lazy的含义,这里就应该很好理解 if(lazy[rt] ) { tree[rt << 1].sum += (tree[rt << 1].r - tree[rt << 1].l + 1) * lazy[rt]; tree[rt << 1 | 1].sum += (tree[rt << 1 | 1].r - tree[rt << 1 | 1].l + 1) * lazy[rt]; lazy[rt << 1] += lazy[rt]; lazy[rt << 1 | 1] += lazy[rt]; lazy[rt] = 0; //完成下放之后应该将当前节点的lazy标记清零 }}void Build(LL rt, LL l, LL r) { tree[rt].l = l, tree[rt].r = r; if(l == r) { tree[rt].sum = a[l]; return; } LL mid = (l + r) >> 1; Build(rt << 1, l, mid); Build(rt << 1 | 1, mid + 1, r); //tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum; push_up(rt);}void update(LL rt, LL L, LL R, LL val){ //如果要更新的区间包含当前节点所代表的区间, //则直接更新这个节点,不再往下更新,并给当前节点打上lazy标记 if(L <= tree[rt].l && tree[rt].r <= R) { tree[rt].sum += (LL)(tree[rt].r - tree[rt].l + 1) * val; lazy[rt] += (LL)val; return ; } //否则,下放lazy标记 并更新左右儿子 push_down(rt); LL mid = (tree[rt].l + tree[rt].r) >> 1; if(L <= mid) update(rt << 1, L, R, val); if(R > mid) update(rt << 1 | 1, L, R, val); //tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum; push_up(rt);}LL query(LL rt, LL L, LL R) { //若要查询的区间完全包含当前节点的区间,则直接返回当前节点的sum if(L <= tree[rt].l && tree[rt].r <= R) return tree[rt].sum; //否则,先下放lazy标记,再进行 左右儿子的查询 push_down(rt); LL mid = (tree[rt].l + tree[rt].r) >> 1; LL res = 0; if(L <= mid) res += query(rt << 1, L, R); if(R > mid) res += query(rt << 1 | 1, L, R); return res;}int main(){ while(scanf("%d %d", &n, &q) != EOF) { for(int i = 1; i <= n; i++) scanf("%lld", &a[i]); Build(1, 1, n); for(int i = 1; i <= q; i++) { char c; scanf(" %c", &c); if(c == 'Q') { LL l, r; scanf("%lld %lld", &l, &r); LL ans = query(1, l, r); printf("%lld\n", ans); } else if(c == 'C') { LL l, r; LL val; scanf("%lld %lld %lld", &l, &r, &val); update(1, l, r, val); //区间更新 } } } return 0;}
阅读全文
0 0
- POJ
- poj
- POJ
- POJ
- poj
- poj
- POJ
- POJ
- poj
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
- FFT学习笔记<理论篇>
- 分享一个Http代理Get请求(C#)
- 第25天
- Sublime 部分快捷键
- POJ
- 整理:C/C++可变参数,“## __VA_ARGS__”宏的介绍和使用
- Python字典的操作
- 基于TensorFlow的车牌号识别系统
- 并查集详解 (转)
- [hdu 6171 Admiral]Hash+暴搜+中途相遇法
- zookeeper分布式锁以及集群
- 华为USG6300系列防火墙 多公网IP端口映射
- 面向对象三大特性之多态