1. 程式人生 > >樹狀陣列(單點修改區間查詢)

樹狀陣列(單點修改區間查詢)

在這裡插入圖片描述

lowbit(重要!)

lowbit是用來取出二進位制中最低位數的1所代表的二進位制的值。
只需要記下程式碼就行了

int lowbit(int x){
	return x&(-x);
}

add單點修改字首和

將一個樹的最子節點修改,則其父節點也需要更改,父父節點也需要修改。x=x+lowbit(x)就是用來取出其父節點的。

void add(int x,int k){
	while(x<=n){
		sum[x]+=k;
		x=lowbit(x)+x;
	}
}

query查詢字首和

字首和

https://blog.csdn.net/johnwayne0317/article/details/84928854

樹狀陣列中的查詢原陣列字首和

能查詢原陣列的字首和,時間複雜度為O(nlogn)
查出其中每個範圍內最父節點的值並相加

int count(int x){
	int cnt=0;
	while(x>0){
		cnt+=sum[x];
		x=x-lowbit(x);
	}
	return cnt;
}

題目連結

https://www.luogu.org/problemnew/show/P3368

程式碼

#include<iostream>
#include <cstdio>
#include <algorithm>
#include
<cstring>
#include <string> using namespace std; int sum[500010]; int n,m; int lowbit(int x){ return x&(-x); } void add(int x,int k){ while(x<=n){ sum[x]+=k; x=lowbit(x)+x; } } int count(int x){ int cnt=0; while(x>0){ cnt+=sum[x]; x=x-lowbit(x); } return cnt; } int main
(){ memset(sum,0,sizeof(sum)); cin>>n>>m; for(int i=1;i<=n;i++){ int tmp2; cin>>tmp2; add(i,tmp2); } for(int j=0;j<m;j++){ int s; cin>>s; int x,k; cin>>x>>k; if(s==1){ add(x,k); }else{ cout<<count(k)-count(x-1)<<endl; } } return 0; }