线段树模板(指针版)

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 const int Maxn = 1000050;
 6 namespace seqtree
 7 {
 8     struct Tree
 9     {
10         Tree *ch[2];
11         long long _v, label;
12         int Num, _l, _r, mid;
13         Tree() { _v = label = 0; Num = 1; }
14         void update();
15         void maintain();
16     }Node[Maxn], *null, *Root;
17     int tot = 0, _k, _L, _R;
18     long long v;
19     void Tree::update()
20     {
21         if(!label) return;
22         _v += Num*label;
23         if(Num != 1) ch[0]->label += label, ch[1]->label += label;
24         label = 0;
25     }
26     void Tree::maintain()
27     {
28         ch[0]->update(); ch[1]->update();
29           _v = ch[0]->_v + ch[1]->_v;
30     }
31     void protect()
32     {
33        null = new Tree();
34       null->ch[0] = null->ch[1] = null; null->Num = 0;
35     }
36     void insert(Tree *&o, int l, int r)
37     {
38         int mid = (l+r)/2;
39         if(o == null)
40         {
41              o = &Node[tot++];
42              o->ch[0] = o->ch[1] = null;
43              o->_l = l; o->_r = r; o->mid = (l+r)/2;
44         }
45         if(l == r) { o->_v = v; return; }
46         if(_k <= mid) insert(o->ch[0], l, mid);
47         else insert(o->ch[1], mid+1, r);
48         o->maintain(); o->Num = o->ch[1]->Num + o->ch[0]->Num;
49     }
50     Tree* Build(int n, long long *a)
51     {
52           protect(); Root = null;
53            for(int i = 1; i <= n; i++) _k = i, v = a[i], insert(Root, 1, n);
54            return Root;
55     }
56     long long query(Tree *o)
57     {
58         long long ans = 0;
59         o->update();
60         if(_L <= o->_l && o->_r <= _R) return o->_v;
61         if(_L <= o->mid) ans += query(o->ch[0]);
62         if(_R > o->mid) ans += query(o->ch[1]);
63         return ans;
64     }
65     long long Query(int L, int R) { _L = L; _R = R; return query(Root); }
66     void change(Tree *o)
67     {
68       o->update();
69       if(_L <= o->_l && o->_r <= _R) { o->label += v; o->update(); return; }
70       if(_L <= o->mid) change(o->ch[0]);   if(_R > o->mid) change(o->ch[1]);
71       o->maintain(); 
72     }
73     void Change(int L, int R, int V) { _L = L; _R = R; v = V; change(Root); }
74 };
75 using namespace seqtree;
76 long long a[Maxn];
77 int main()
78 {    
79     int n, x;
80     freopen("a.txt", "r", stdin);
81     scanf("%d", &n);
82     for(int i = 1; i <= n; i++) scanf("%lld", &a[i]);
83     Build(n, a);
84     int Q, L, R;
85     scanf("%d", &Q);
86     while(Q--)
87     {
88         scanf("%d", &x);
89         if(x == 0)
90         {
91             scanf("%d %d %d", &L, &R, &x);
92             Change(L, R, x);
93         }else 
94         {
95             scanf("%d %d", &L, &R);
96             printf("%lld
", Query(L, R));
97         }
98     }
99 }
原文地址:https://www.cnblogs.com/Saurus/p/5981310.html