線段樹(點修改)

線段樹是一種數據結構……有了線段樹,咱們就能夠對一個序列進行快速修改並查詢某個區間內的最大值、最小值、和等……下面我來講一下線段樹是如何實現的ios

線段樹就是一棵二叉樹,咱們對一棵二叉樹上的點依次編號,從根節點開始,咱們從1開始編號,而後對於每一層的點從左到右編號,這樣咱們不難發現有一個很重要的性質,就是對於任意一個非葉子節點,他的左兒子的編號必定是這個節點乘2,右兒子就是這個節點的編號乘2加1。數據結構

我對於每個節點中儲存這個節點的全部的兒子節點的最大值、最小值、和,那麼咱們就必定能夠在log(n)的時間內對於要修改的點進行更新,或者對於某個區間進行查詢。ui

線段樹一開始確定感受有點亂,但最主要的仍是看看代碼,好好研究一下代碼是怎麼寫的,而後慢慢理解……我是在學了C++半年以後纔開始學線段樹的……我一開始反正沒懂……spa

代買以下(這就是對於一個序列的點修改和區間查詢的代碼):code

 1 #include<iostream>
 2 #define maxn 1000000
 3 #define INF 2000000000
 4 using namespace std;
 5 int a[maxn],maxv[3*maxn],minv[3*maxn],sumv[3*maxn];
 6 void build(int L,int R,int o)
 7 {
 8     if(L==R)maxv[o]=minv[o]=sumv[o]=a[L];
 9     else
10     {
11         int m=L+(R-L)/2,lc=o<<1,rc=lc+1;
12         build(L,m,lc);
13         build(m+1,R,rc);
14         maxv[o]=max(maxv[lc],maxv[rc]);
15         minv[o]=min(minv[lc],minv[rc]);
16         sumv[o]=sumv[lc]+sumv[rc];
17     }
18     return;
19 }
20 int x,v;
21 void update(int L,int R,int o)
22 {
23     if(L==R)maxv[o]=minv[o]=sumv[o]=v;
24     else
25     {
26         int m=L+(R-L)/2,lc=o<<1,rc=lc+1;
27         if(x<=m)update(L,m,lc);
28         if(x>m)update(m+1,R,rc);
29         maxv[o]=max(maxv[lc],maxv[rc]);
30         minv[o]=min(minv[lc],minv[rc]);
31         sumv[o]=sumv[lc]+sumv[rc];
32     }
33 }
34 int ql,qr,_max,_min,_sum;
35 void query(int L,int R,int o)
36 {
37     if(ql<=L&&R<=qr)
38     {
39         _max=max(_max,maxv[o]);
40         _min=min(_min,minv[o]);
41         _sum+=sumv[o];
42     }
43     else 
44     {
45         int m=L+(R-L)/2,lc=o<<1,rc=lc+1;
46         if(ql<=m)query(L,m,lc);
47         if(qr>m)query(m+1,R,rc);
48     }
49     return;
50 }
51 int main()
52 {
53     int n,Q;
54     scanf("%d",&n);
55     for(int i=1;i<=n;i++)
56     {
57         scanf("%d",&a[i]);
58     }
59     build(1,n,1);
60     scanf("%d",&Q);
61     while(Q--)
62     {
63         char t;
64         scanf("%s",&t);
65         if(t=='Q')
66         {
67             _sum=0;
68             _min=-1u>>1;
69             _max=1<<31;
70             scanf("%d%d",&ql,&qr);
71             query(1,n,1);
72             printf("MaxNum: %d, MinNum: %d, Sum: %d\n",_max,_min,_sum);
73         }
74         if(t=='C')
75         {
76             scanf("%d%d",&x,&v);
77             update(1,n,1);
78         }
79     }
80 }
相關文章
相關標籤/搜索