标记不下传线段树(混蛋树)

开坑开坑 KL ZXR都写了 不能懒了

*************************************

万年大坑

*************************************

ZXR是大神犇

*************************************

我当然是抄了一份

*************************************

标记不下船线段树 (sign not leave the boat)


把线段树的一个lazy标记变成两个来避免pushdown

s:表示当前增量cover当前节点

f:表示当前增量belongto当前节点

因此

更新是更新链上的所有f(去搅基)和终点节点的s

查询时累加链上的s(去搅基)和终点节点的f

*************************************

ZXR真是吊

*************************************

处理更改标记:

好像只能转化成增量。。。。。我不知道

YMZXR
 1 #include <cstdio>
 2 #include <iostream>
 3 using namespace std;
 4 #define lson l, m, idx << 1
 5 #define rson m + 1, r, idx << 1 | 1
 6 const int N = 101000;
 7 typedef long long LL;
 8 LL sum[N], f[N << 1], s[N << 2], ans;
 9 int n, q, a[N]; 
10 //s : cover
11 //f : belong
12 inline void updata (int c, int L, int R, int l, int r, int idx)
13 {
14     if (L <= l && r <= R)
15     {
16         s[idx] += c;
17         return ;
18     }
19     f[idx] += c * (min (R, r) - max (L, l) + 1);
20     int m = l + r >> 1;
21     if (L <= m) updata (c, L, R, lson);
22     if (R > m) updata (c, L, R, rson);
23 }
24 inline void query (int L, int R, int l, int r, int idx)
25 {
26     ans += s[idx] * (min (R, r) - max (L, l) + 1);
27     if (L <= l && r <= R)
28     {
29         ans += f[idx];
30         return ;
31     }
32     
33     int m = l + r >> 1;
34     if (L <= m) query (L, R, lson);
35     if (R > m) query (L, R, rson);
36 }
37 int main ()
38 {
39     scanf ("%d%d", &n, &q);
40     for (int i = 1; i <= n; i ++)
41         scanf ("%d", &a[i]), sum[i] = sum[i - 1] + a[i];
42     char s[10];
43     long long c;
44     for (int i = 1, a, b; i <= q; i ++)
45     {
46         scanf ("%s", s);
47         if (s[0] == 'Q')
48             scanf ("%d%d", &a, &b), ans = 0, query (a, b, 1, n, 1), printf ("%lld\n", sum[b] - sum[a - 1] + ans);
49         if (s[0] == 'C')
50             scanf ("%d%d%lld", &a, &b, &c), updata (c, a, b, 1, n, 1);
51     }
52     return 0;
53 }
原文地址:https://www.cnblogs.com/tellmewtf/p/2853731.html