【模板】 线段树(部分功能)

嗯...

这个模板里有线段树的建树、标记下放、单点查询、单点加、区间和、单点更改。

 

代码:

 1 struct Tree{
 2     int l,r,f = 0;
 3     long long wi;
 4 }tree[Maxn*3];
 5 
 6 void build(int le,int ri,int k){
 7     tree[k].l = le;
 8     tree[k].r = ri;
 9     if(le == ri){
10         scanf("%lld",&tree[k].wi);
11         return;
12     }
13     int m = (le + ri)/2;
14     build(le,m,k*2);
15     build(m+1,ri,k*2+1);
16     tree[k].wi = tree[k*2].wi + tree[k*2+1].wi;
17 }//建树 
18 
19 void down(int k){
20     tree[k*2].f += tree[k].f;
21     tree[k*2+1].f += tree[k].f;
22     tree[k*2].wi += tree[k].f*(tree[k*2].r + 1 - tree[k*2].l);
23     tree[k*2+1].wi += tree[k].f*(tree[k*2+1].r + 1 - tree[k*2+1].l);
24     tree[k].f = 0;
25 }//标记下放 
26 
27 void ask(int k){
28     if(tree[k].l == tree[k].r){
29         ans = tree[k].wi;
30         return;
31     }
32     if(tree[k].f)down(k);
33     int m = (tree[k].l + tree[k].r)/2;
34     if(x <= m)ask(k*2);
35     else ask(k*2+1);
36 }//单点查询 
37 
38 void add(int k){
39     if(tree[k].l == tree[k].r){
40         tree[k].wi += y;
41         return;
42     }
43     if(tree[k].f)down(k);
44     int m = (tree[k].l + tree[k].r)/2;
45     if(x <= m)add(k*2);
46     else add(k*2+1);
47     tree[k].wi = tree[k*2].wi + tree[k*2+1].wi;
48 }//单点加 
49 
50 void sum(int k){
51     if(x <= tree[k].l && tree[k].r <= y){
52         ans += tree[k].wi;
53         return;
54     }
55     if(tree[k].f)down(k);
56     int m = (tree[k].l+tree[k].r)/2;
57     if(x <= m)sum(k*2);
58     if(y > m)sum(k*2+1);
59 }//区间和 
60 
61 void change(int k){
62     if(x <= tree[k].l && tree[k].r <= y){
63         tree[k].f+=z;
64         tree[k].wi += z*(tree[k].r + 1 - tree[k].l);
65         return;
66     }
67     if(tree[k].f)down(k);
68     int m = (tree[k].l + tree[k].r)/2;
69     if(x <= m)change(k*2);
70     if(m < y)change(k*2+1);
71     tree[k].wi = tree[k*2].wi + tree[k*2+1].wi;
72 }//单点修改 
模板
原文地址:https://www.cnblogs.com/New-ljx/p/11180203.html