【高级数据结构】树状数组

 

目录

 

树状数组1 (单点修改,区间查询)


树状数组1 (单点修改,区间查询)

洛谷:树状数组1https://www.luogu.com.cn/problem/P3374

题目描述

如题,已知一个数列,你需要进行下面两种操作:

  • 将某一个数加上 x

  • 求出某区间每一个数的和

输入格式

第一行包含两个正整数 n,m,分别表示该数列数字的个数和操作的总个数。

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

接下来 m 行每行包含 33 个整数,表示一个操作,具体如下:

  • 1 x k 含义:将第 x 个数加上 k

  • 2 x y 含义:输出区间 [x,y] 内每个数的和

输出格式

输出包含若干行整数,即为所有操作 22 的结果。

输入输出样例

输入 #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
// Problem: P3374 【模板】树状数组 1
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3374
// Memory Limit: 512 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include
using namespace std;

typedef long long ll;

const int N = 5e6+5;  

int a[N];
ll c[N];   //代表的是 a(i-lowbit(i)+1) --> ai 的和
int n,q;

ll query(ll x){  
	ll s=0;
	for(;x;x-=x&(-x)){
		s+=c[x];
	}
	return s;
}

void modify(ll x,ll s){   //c[x]加上s
	for(;x<=n;x+=x&(-x)){
		c[x]+=s;
	}
}

int main(){
	cin>>n>>q;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		modify(i,a[i]);
	}
	for(int i=0;i>ty;
		ll x,d;
		cin>>x>>d;
		if(ty==1){
			modify(x,d);
			a[x]=d;
		}
		else{
			cout<

 

树状数组2(区间修改,单点查询)

洛谷:树状数组2icon-default.png?t=N6B9https://www.luogu.com.cn/problem/P3368

题目描述

如题,已知一个数列,你需要进行下面两种操作:

  1. 将某区间每一个数加上 x;

  2. 求出某一个数的值。

输入格式

第一行包含两个整数 N、M,分别表示该数列数字的个数和操作的总个数。

第二行包含 N 个用空格分隔的整数,其中第 i 个数字表示数列第 i 项的初始值。

接下来 M 行每行包含 22 或 44个整数,表示一个操作,具体如下:

操作 11: 格式:1 x y k 含义:将区间 [x,y] 内每个数加上 k;

操作 22: 格式:2 x 含义:输出第 x 个数的值。

输出格式

输出包含若干行整数,即为所有操作 22 的结果。

输入输出样例

输入 #1复制

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

输出 #1复制

6
10

 

你可能感兴趣的:(数据结构,算法,c++,学习)