信奧一本通-樹狀數組模版題目-修改數列元素+求子數列元素和

給定n個數列,規定有兩種操做,一是修改某個元素,二是求子數列[a,b]的連續和。數列的元素個數最多10萬個,詢問操做最多10萬次。

 
輸入
第一行2個整數n,m(n表示輸入n個數,m表示有m個操做)
第二行輸入n個數列。
接下來m行,每行有三個數k,a,b(k=0表示求子數列[a,b]的和;k=1表示第a個數加b)。

 
輸出
輸出若干行數字,表示k=0時,對應的子數列[a,b]的連續和。


樣例輸入
10 5
1 2 3 4 5 6 7 8 9 10
1 1 5
0 1 3
0 4 8
1 7 5
0 4 8
 

樣例輸出
11
30
35
 

 

模板題。信奧p211ios

記住三步操做:求lowbit、對某個元素進行加法操做、查詢某個前綴和。數組

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<iostream>
 6 using namespace std;
 7 const int N=1e5+10;
 8 int n,c[N];
 9 
10 int lowbit(int x)
11 {
12     return x&(-x);
13 }
14 
15 void update(int x,int k)//在第x個位置(數)上加上k,並在樹狀數組中修改相應元素//對某個元素進行加法操做
16 {
17     while(x<=n)
18     {
19         c[x]+=k;
20         x+=lowbit(x);
21     }
22 }
23 
24 int sum(int x)//查詢前綴和 25 {
26     int res=0;
27     while(x>0)
28     {
29         res+=c[x];
30         x-=lowbit(x);
31     }
32     return res;
33 }
34 
35 int main()
36 {
37     int m,k;
38     scanf("%d %d",&n,&m);
39     for(int i=1; i<=n; i++)
40     {
41         scanf("%d",&k);
42         update(i,k);
43     }
44     for(int i=1; i<=m; i++)
45     {
46         int kk,a,b;
47         scanf("%d %d %d",&kk,&a,&b);
48         if(kk==0)//求區間和且輸出
49         {
50             int ans=sum(b)-sum(a-1);
51             printf("%d\n",ans);
52         }
53         else if(kk==1)//把第a個位置的元素更改成b
54             update(a,b);
55     }
56     return 0;
57 }
相關文章