线段树

Posted zcmimi

tags:

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

 1 #include<bits/stdc++.h>
 2 #define mx 1001
 3 using namespace std;
 4 int n,a[mx],sum[mx],add[mx],q;
 5 void pu(int rt){sum[rt]=sum[rt*2]+sum[rt*2+1];}
 6 void pd(int rt,int ln,int rn){
 7     if(add[rt]){
 8         add[rt*2]+=add[rt];
 9         add[rt*2+1]+=add[rt];
10         sum[rt*2]+=add[rt]*ln;
11         sum[rt*2+1]+=add[rt]*rn;
12         add[rt]=0;
13     }
14 }
15 void build(int l,int r,int rt){
16     if(l==r){
17         sum[rt]=a[l];
18         return;
19     }
20     int mid=(l+r)/2;
21     build(l,mid,rt*2);
22     build(mid+1,r,rt*2+1);
23     pu(rt);
24 }
25 void upd(int L,int c,int l,int r,int rt){
26     if(l==r){sum[rt]+=c;return;}
27     int mid=(l+r)/2;
28     if(L<=mid)upd(L,c,l,mid,rt*2);
29     else upd(L,c,mid+1,r,rt*2+1);
30     pu(rt);
31 }
32 void upd(int L,int R,int c,int l,int r,int rt){
33     if(L<=l&&r<=R){
34         sum[rt]+=c*(r-l+1);
35         add[rt]+=c;
36         return;
37     }
38     int mid=(l+r)/2;
39     if(L<=mid)upd(L,R,c,l,mid,rt*2);
40     if(R>mid)upd(L,R,c,mid+1,r,rt*2+1);
41     pu(rt);
42 }
43 int qh(int L,int R,int l,int r,int rt){
44     if(L<=l&&r<=R)return sum[rt];
45     int ans=0;
46     int mid=(l+r)/2;
47     if(L<=mid)ans+=qh(L,R,l,mid,rt*2);
48     if(R>mid)ans+=qh(L,R,mid+1,r,rt*2);
49     return ans;
50 }
51 int main(){
52     scanf("%d%d",&n,&q);
53     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
54     build(1,n,1);
55     int x,y,c,k;
56     while(q--){
57         scanf("%d%d%d",&c,&x,&y);
58         if(c==0)printf("%d\n",qh(x,y,1,n,1));
59         if(c==1)upd(x,y,1,n,1);
60         if(c==2){
61             scanf("%d",&k);
62             upd(x,y,k,1,n,1);
63         }
64     }
65 }

 

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

线段树

CCF(除法):线段树区间修改(50分)+线段树点修改(100分)+线段树(100分)

线段树合并

数据结构——线段树

论线段树:二

线段树