线段树模板

 1 #include<iostream>
 2 
 3 #define maxn 100007
 4 using namespace std;
 5 
 6 int Sum[maxn<<2],lazy[maxn<<2];
 7 int a[maxn],n;
 8 
 9 void Pushup(int rt){Sum[rt]=Sum[rt<<1]+Sum[rt<<1|1];}//更新节点信息
10 //建树
11 void Build(int l,int r,int rt)//l,r当前节点区间,rt当前节点编号;
12 {
13     if(l==r)
14     {
15         Sum[rt]=a[l];
16         return ;
17     }
18 
19     int m=(l+r)>>1;
20 
21     Build(l,m,rt<<1);
22     Build(m+1,r,rt<<1|1);
23 
24     Pushup(rt);
25 }
26 
27 //下推懒标记
28 void Pushdown(int rt,int ln,int rn)//ln rn 左子树右子树数字数量
29 {
30     if(lazy[rt])
31     {
32         lazy[rt<<1]+=lazy[rt];
33         lazy[rt<<1|1]+=lazy[rt];
34 
35         Sum[rt<<1]+=lazy[rt]*ln;
36         Sum[rt<<1|1]+=lazy[rt]*rn;
37 
38         lazy[rt]=0;
39     }
40 }
41 
42 //更新节点
43 void Update(int L,int C,int l,int r,int rt)//a[L]=C
44 {
45     if(l==r)
46     {
47         Sum[rt]+=C;
48         return ;
49     }
50 
51     int m=(l+r)>>1;
52     Pushdown(rt,m-l+1,r-m);
53 
54     if(L<=m)Update(L,C,l,m,rt<<1);
55     else
56         Update(L,C,m+1,r,rt<<1|1);
57 
58     Pushup(rt);
59 }
60 
61 //更新区间
62 void update(int L,int R,int C,int l,int r,int rt)//L,R操作区间 l,r当前区间rt节点
63 {
64     if(L<=l&&r<=R)
65     {
66         Sum[rt]+=C*(r-l+1);
67         lazy[rt]+=C;
68         return ;
69     }
70     int m=(l+r)>>1;
71     Pushdown(rt,m-l+1,r-m);
72 
73     if(L<=m)update(L,R,C,l,m,rt<<1);
74     if(R>m)update(L,R,C,m+1,r,rt<<1|1);
75     Pushup(rt);
76 }
77 //查询区间
78 int Query(int L,int R,int l,int r,int rt)
79 {
80     if(L<=l&&r<=R)
81     {
82         return Sum[rt];
83     }
84 
85     int m=(l+r)>>1;
86     Pushdown(rt,m-l+1,r-m);
87 
88     int ans=0;
89     if(L<=m)ans+=Query(L,R,l,m,rt<<1);
90     if(R>m)ans+=Query(L,R,m+1,r,rt<<1|1);
91     return ans;
92 }
93 
94 
95 //函数调用
96 Build(1,n,1);
97 Update(L,C,1,n,1);
98 update(L,R,C,1,n,1);
99 int ans=Query(L,R,1,n,1);

 

posted @ 2018-02-01 12:59  reminito  阅读(74)  评论(0编辑  收藏  举报