1. 程式人生 > 其它 >15.【模板】樹狀陣列1

15.【模板】樹狀陣列1

技術標籤:演算法演算法資料結構

15.【模板】樹狀陣列1

題目描述

如題,已知一個數列,你需要進行下面兩種操作:

  • 將某一個數加上 x
  • 求出某區間每一個數的和

輸入格式

第一行包含兩個正整數 n,m,分別表示該數列數字的個數和操作的總個數。

第二行包含 n 個用空格分隔的整數,其中第 i 個數字表示數列第 i 項的初始值。

接下來 m 行每行包含 3 個整數,表示一個操作,具體如下:

  • 1 x k 含義:將第 x 個數加上 k
  • 2 x y 含義:輸出區間 [x,y] 內每個數的和

輸出格式

輸出包含若干行整數,即為所有操作 2 的結果。

輸入輸出樣例

輸入 #1複製

5 5
1 5 4 2 3
1 1 3
2 2 5
1 3 -1
1 4 2
2 1 4

輸出 #1複製

14
16

說明/提示

【資料範圍】

對於 30%30% 的資料,1 \le n \le 81≤n≤8,1\le m \le 101≤m≤10;
對於 70%70% 的資料,1\le n,m \le 10^41≤n,m≤104;
對於 100%100% 的資料,1\le n,m \le 5\times 10^51≤n,m≤5×105。

樣例說明:

img

故輸出結果14、16

題解

#include<iostream>
using namespace std;
#define maxn 500005
int n,m;

int a[maxn],c[maxn];

int lowbit(int x)
{ return x&(-x); } void update(int x,int y) { while(x<=n) { c[x]+=y; x+=lowbit(x); } } int ssum(int x) { int res=0; while(x>0) { res+=c[x]; x-=lowbit(x); } return res; } int main() { cin>>n>>m; for(int
i=1;i<=n;i++) { cin>>a[i]; update(i,a[i]); } int p1,x,y; for(int i=1;i<=m;i++) { cin>>p1>>x>>y; switch(p1) { case 1:update(x,y);break; case 2:cout<<ssum(y)-ssum(x-1)<<endl;break; default:break; } } }