线段树2(区间修改,lazy)

来源:互联网 发布:政府购买社会服务数据 编辑:程序博客网 时间:2024/05/06 18:33

每次对于修改的不是一个数而是一个区间的情况我们可以采用lazy的方法来偷懒,达到减少操作步骤的效果。

具体思路是当要修改某个区间 时,和查找的方法一样先找在线段树中对应 到要修改的几个小区间,然后修个这些区间节点的值,但不同的是先不再对下面细分的区间进行修改。

我们偷懒的原则是后面不访问的就暂时不修改,等到要访问的时候再随便把lazy下放到子区间,并把当前的lazy标记 消除。


#include <stdio.h>#include <iostream>#include <algorithm>#include <string.h>#include<string>#include <math.h>#define MOD 1000000007;using namespace std;struct  node{int v;int l;int r;node(int a, int b, int c){v = a;l = b;r = c;lazy = false;lazynum = 0;}node(){v = 0;l = 0;r = 0;lazy = false;lazynum = 0;}bool lazy;int lazynum;};node ltree[4000005];int z[1000005];int N, Q, x, L, R, v;int creata(int now, int l, int r){ltree[now].l = l;ltree[now].r = r;if (l == r){ltree[now].v = z[l];return z[l];}int m = (l + r >> 1);ltree[now].v = creata(now * 2, l, m) + creata(now * 2 + 1, m + 1, r);return ltree[now].v;}int find(int now, int l, int r, bool isfix){if (ltree[now].l == l && ltree[now].r == r){if (isfix){ltree[now].lazy = true;ltree[now].lazynum = v;ltree[now].v = (r - l + 1)*v;}return ltree[now].v;}int m = (ltree[now].l + ltree[now].r >> 1);if (ltree[now].lazy){ltree[now * 2].lazy = ltree[now * 2 + 1].lazy = true;ltree[now * 2].lazynum = ltree[now * 2 + 1].lazynum = ltree[now].lazynum;ltree[now * 2].v = ltree[now].lazynum *(ltree[now * 2].r - ltree[now * 2].l + 1);ltree[now * 2 + 1].v = ltree[now].lazynum * (ltree[now * 2 + 1].r - ltree[now * 2 + 1].l + 1);ltree[now].lazy = false;}if (isfix){if (r <= m){ltree[now].v = find(now * 2, l, r, isfix) + ltree[now * 2 + 1].v;}else if (l > m){ltree[now].v = ltree[now * 2].v + find(now * 2 + 1, l, r, isfix);}else{ltree[now].v = find(now * 2, l, m, isfix) + find(now * 2 + 1, m + 1, r, isfix);}return ltree[now].v;}else{if (r <= m){return find(now * 2, l, r, isfix);}else if (l > m){return find(now * 2 + 1, l, r, isfix);}else{return find(now * 2, l, m, isfix) + find(now * 2 + 1, m + 1, r, isfix);}}}int main(){while (~scanf("%d", &N)){for (int i = 1; i <= N; ++i){scanf("%d", &z[i]);}creata(1, 1, N);scanf("%d", &Q);for (int i = 0; i < Q; ++i){scanf("%d %d  %d", &x, &L, &R);if (x){scanf("%d", &v);find(1, L, R, true);}else{printf("%d\n", find(1, L, R, false));}}}return 0;}


0 0
原创粉丝点击