每次对于修改的不是一个数而是一个区间的情况我们可以采用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;
}