模板:线段树

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板:线段树相关的知识,希望对你有一定的参考价值。

 1 typedef long long LL;
 2 LL ans;
 3 
 4 struct Tree
 5 {
 6     LL l,r;
 7     LL sum,add;
 8 };
 9 Tree tree[4*N];
10 
11 void pushup(LL x)
12 {
13     LL tmp=x<<1;
14     tree[x].sum=tree[tmp].sum+tree[tmp+1].sum;
15 }
16 
17 void pushdown(LL x) 
18 {
19     LL tmp=x<<1;
20     tree[tmp].add+=tree[x].add;
21     tree[tmp+1].add+=tree[x].add;
22     tree[tmp].sum+=tree[x].add*(tree[tmp].r-tree[tmp].l+1);
23     tree[tmp+1].sum+=tree[x].add*(tree[tmp+1].r-tree[tmp+1].l+1);
24     tree[x].add=0;
25 }
26 
27 void build(LL l,LL r,LL x)
28 {
29     tree[x].l=l;
30     tree[x].r=r;
31     tree[x].add=0;
32     if(l==r)
33     {
34         scanf("%lld",&tree[x].sum);
35         return ;
36     }    
37     LL tmp=x<<1;
38     LL mid=(l+r)>>1;
39     build(l,mid,tmp);
40     build(mid+1,r,tmp+1);
41     pushup(x);
42 }
43 
44 void update(LL l,LL r,LL c,LL x)
45 {
46     if(r<tree[x].l||l>tree[x].r) return ;
47     if(l<=tree[x].l&&r>=tree[x].r)
48     {
49         tree[x].add+=c;
50         tree[x].sum+=c*(tree[x].r-tree[x].l+1);
51         return ;    
52     }
53     if(tree[x].add) pushdown(x);
54     LL tmp=x<<1;
55     LL mid=(tree[x].l+tree[x].r)>>1;
56     if(r<=mid) update(l,r,c,tmp);
57     else if(l>mid) update(l,r,c,tmp+1);
58     else
59     {
60         update(l,mid,c,tmp);
61         update(mid+1,r,c,tmp+1);    
62     }
63     pushup(x);
64 }
65 
66 void query(LL l,LL r,LL x)
67 {
68     if(r<tree[x].l||l>tree[x].r) return ;
69     if(l<=tree[x].l&&r>=tree[x].r)
70     {
71         ans+=tree[x].sum;
72         return ;
73     }
74     if(tree[x].add) pushdown(x);    
75     LL tmp=x<<1;
76     LL mid=(tree[x].l+tree[x].r)>>1;
77     if(r<=mid) query(l,r,tmp);
78     else if(l>mid) query(l,r,tmp+1);
79     else
80     {
81         query(l,mid,tmp);
82         query(mid+1,r,tmp+1);    
83     }
84 }

 

以上是关于模板:线段树的主要内容,如果未能解决你的问题,请参考以下文章

线段树模板整理

线段树模板总结

线段树模板

模板线段树-单点修改,区间查询

P3834 模板可持久化线段树 1(主席树)

模板 线段树(部分功能)