1. 程式人生 > 其它 >數列操作 資訊學奧賽一本通--T1535(樹狀陣列)

數列操作 資訊學奧賽一本通--T1535(樹狀陣列)

技術標籤:樹狀陣列資料與結構c++

原題連結

【題目描述】
給定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

這個題剛開始看感覺好簡單,就直接寫,結果沒有通過,超時了

在這裡插入圖片描述
後來在網上查了查解題需要用到樹狀陣列,這個樹狀陣列我覺得如果理解了寫題就很方便,並且樹狀陣列可以實現區間查詢和單點修改,並且對於這個題裡的要求

數列元素個數最多10萬個,詢問操作最多10萬次。

可以高效實現,注意這個題需要大量輸入和輸出所以要使用scanf和printf函式輸入和輸出。
我在網上看的樹狀陣列是通過這個部落格寫的很清楚明白,並且把樹狀陣列介紹的很清楚。我還得再寫幾個題好好練練,再好好理解理解。

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define maxn 100100 int c[maxn]; int n,m; int lowbit(int x){return x&(-x);} void update(int a,int b) { for(int i=a;i<=n;i=i+lowbit(i)) c[i]+=b; } int isum(int a) { int nsum=0; for(int i=a;i>0;i=i-lowbit(i)) nsum+=c[i]; return nsum; } int main() { memset(c,0,sizeof(c)); int x; scanf("%d%d"
,&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&x); update(i,x); } int k,a,b; while(m--) { scanf("%d%d%d",&k,&a,&b); if(k==1) update(a,b); else printf("%d\n",isum(b)-isum(a-1)); } return 0; }