专栏文章

P3368 【模板】树状数组 2 题解

P3368题解参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@mipipym2
此快照首次捕获于
2025/12/03 12:39
3 个月前
此快照最后确认于
2025/12/03 12:39
3 个月前
查看原文
树状数组是单点修改、区间查询,而这题是区间修改、单点查询,相当于动态的差分,维护差分数组就可以单点修改、区间查询。
设这个序列是 aa,它的长度是 nn,它的差分数组是 dd,即对于所有整数 j[2,n]j\in[2,n] 都有 dj=ajaj1d_j=a_j-a_{j-1},特别地 d1=a1d_1=a_1,显然 ax=i=1xdia_x=\sum\limits_{i=1}^x d_i
当执行操作 11,区间 [x,y][x,y] 内每个数都加上 kk 的时候,dxd_x 加上 kkdy+1d_{y+1} 减去 kk(当 y=ny=n 时不减)。
当执行操作 22,要输出 axa_x 的值时,输出 i=1ndi\sum\limits_{i=1}^n d_i 就好了。
dd 用树状数组维护,时间复杂度 O(MlogN)O(M\log N),空间复杂度 O(N)O(N),不会爆。
代码如下。
CPP
#include <iostream>
#define int long long
using namespace std;
int n,q,c[1000001];
void upd(int i,const int x) {
	for(;i<=n;i+=i&-i) c[i]+=x;
}
int query(int i) {
	int ret=0;
	for(;i;i-=i&-i) ret+=c[i];
	return ret;
}
signed main() {
	cin.tie(nullptr)->sync_with_stdio(false),
	cout.tie(nullptr);
	cin>>n>>q;
	for(int a,i=1;i<=n;i++) {
		cin>>a;
		upd(i,a);
		upd(i+1,-a);
	}
	for(int op,l,r,x;q--;) {
		cin>>op;
		if(op==1) {
			cin>>l>>r>>x;
			upd(l,x);
			upd(r+1,-x);
		} else {
			cin>>x;
			cout<<query(x)<<'\n';
		}
	}
	return 0;
}

评论

1 条评论,欢迎与作者交流。

正在加载评论...