1. 程式人生 > >樹狀數組維護前綴和

樹狀數組維護前綴和

print getchar() 都是 clu tro pda i++ 分享圖片 前綴

樹狀數組是用來維護序列前綴和的數據結構。它的修改與求和都是O(logn)的,效率非常高。

我們設序列為A,則樹狀數組c中,c[i]記錄序列A的區間[ i-lowbit(i)+1 , i ]中所有數的和。 (樹狀數組是個好東西ovo) 技術分享圖片

樹狀數組在進行區間操作時,要從上到下訪問,進行單點操作時,要從下到上訪問。

樹狀數組維護序列前綴和的模版如下:

#include <iostream>
#include <cstdio>
#define maxn 500005
using namespace std;

int n,m;
int c[maxn];//c[i]存序列a中i-lowbit(i)+1到i的所有數的和(樹狀數組)
int read() { int f=1,x=0; char ch; while(ch<0||ch>9) { if(ch==-)f=-1; ch=getchar(); } while(ch>=0&&ch<=9) { x=x*10+ch-0; ch=getchar(); } return f*x; } int lowbit(int x) { return
x&(-x); } void update(int x,int y) { while(x<=n) { c[x]+=y; x+=lowbit(x); } }//將序列a[x]加上y int sum(int x) { int res=0; while(x>0) { res+=c[x]; x-=lowbit(x); } return res; }//求序列1-x的和 int main() { n=read();m=read();
for(int i=1;i<=n;i++) { //a[i]=read(); int v=read(); update(i,v); } for(int i=1;i<=m;i++) { int op,x,y; op=read();x=read();y=read(); if(op==1) { update(x,y); } if(op==2) { int ans=sum(y)-sum(x-1); printf("%d\n",ans); } } return 0; }

樹狀數組維護前綴和