树状数组模板

单点修改,区间查询

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
int t[50005],a[50005];
int n;
void add(int x,int k) {
	for(; x<=n; x+=x&-x)t[x]+=k;
}
int ask(int x) {
	int ans=0;
	for(; x; x-=x&-x)ans+=t[x];
	return ans;
}
int main() {
	for(int i=1; i<=n; i++) {
		cin>>a[i];
		add(i,a[i]);
	}
	add(x,val);//单点修改 
	int cnt=ask(b)-ask(a-1);//计算区间和 
}

区间修改,单点查询

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
int t[50005],a[50005];
int n;
void add(int x,int k) {
	for(; x<=n; x+=x&-x)t[x]+=k;
}
int ask(int x) {
	int ans=0;
	for(; x; x-=x&-x)ans+=t[x];
	return ans;
}
int main() {
	cin>>n;
	for(int i=1; i<=n; i++) {
		cin>>a[i];
	}
	int l,r,val;
	add(l,val);
	add(r+1,-val);//区间修改
	
	int x;
	cout<<a[x]+ask(x); //单点查询 

}

区间修改,区间查询

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define MAXN 100005
using namespace std;
long long t1[MAXN],t2[MAXN];
long long sum[MAXN],a[MAXN];
int n,m;
//区间修改,区间查询
void add1(int x,int k) {
	for(; x<=n; x+=x & -x) t1[x]+=k;
}
long long ask1(int x) {
	long long ans=0;
	for(; x; x-=x & -x)ans+=t1[x];
	return ans;
}
void add2(int x,int k) {
	for(; x<=n; x+=x & -x) t2[x]+=k;
}
long long ask2(int x) {
	long long ans=0;
	for(; x; x-=x & -x)ans+=t2[x];
	return ans;
}
long long query(int l,int r){//区间查询
	long long ans=
	    (sum[r]+(r+1)*ask1(r)-ask2(r))-
	    (sum[l-1]+l*ask1(l-1)-ask2(l-1));
	return ans;
}
void modify(int l,int r,int d){//区间修改
	add1(l,d);
	add1(r+1,-d);
	add2(l,l*d);
	add2(r+1,-d*(r+1));
}
int main () {
	cin>>n;
	for (int i=1; i<=n; i++) {
		cin>>a[i];
		sum[i]=sum[i-1]+a[i];
	}
	
	//区间查询
	int l,r,d;cin>>l,r;
	long long ans=query(l,r);
	
	//区间修改
	cin>>l>>r>>d;
	modify(l,r,d);
}



posted @ 2021-07-29 15:35  cheems~  阅读(23)  评论(0编辑  收藏  举报