关于超级树状数组
  • 板块学术版
  • 楼主wo_hen_la
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/3/11 20:56
  • 上次更新2024/3/11 23:33:57
查看原帖
关于超级树状数组
794701
wo_hen_la楼主2024/3/11 20:56

rt,问题在注释

/*
d[i]=a[i]-a[i-1];
a[i]=d[1]+d[2]...+d[i]
sum[1][n]=d[1]+(d[1]+d[2])+(d[1]+d[2]+d[3])
		 =n*sum(d[1]~d[n])-sum(d[i]*(i-1))
*/

#include <bits/stdc++.h>
#define int long long
#define N 200005
using namespace std;
int tr1[N],tr2[N];
int n,m,a[N],val;
void add1(int k,int v)
{
	while(k<=n){
		tr1[k]+=v;
		k+=k & -k;
	}
}
void add2(int k,int v)
{
	while(k<=n){
		tr2[k]+=v;
		k+=k & -k;
	}
}
int query1(int k)
{
	int cnt=0;
	while(k){
		cnt+=tr1[k];
		k-=k & -k;
	}
	return cnt;
}
int query2(int k)
{
	int cnt=0;
	while(k){
		cnt+=tr2[k];
		k-=k & -k;
	}
	return cnt;
}
void modify(int l,int r,int v)
{
	add1(l,v);add1(r+1,-v);
	add2(l,v*(l-1));add2(r+1,-v*r);
}
int out(int l,int r)
{
	/*
	d[i]=a[i]-a[i-1];
	a[i]=d[1]+d[2]...+d[i]
	sum[1][n]=d[1]+(d[1]+d[2])+(d[1]+d[2]+d[3])
		=n*sum(d[1]~d[n])-sum(d[i]*(i-1))
	*/
	//query是单点查询的,为什么能求出sum(d[1]~d[n])
	int suml=query1(l-1)*(l-1)-query2(l-1);
	int sumr=query1(r)*r-query2(r);
	return sumr-suml;
}
main()
{
	ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		val=a[i]-a[i-1];
		add1(i,val);add2(i,val*(i-1));
	}
	while(m--){
		int op,x,y,k;
		cin>>op>>x>>y;
		if(op==1){
			cin>>k;
			modify(x,y,k);
		}else{
			cout<<out(x,y)<<"\n"; 
		}
	} 
	return 0;
}

2024/3/11 20:56
加载中...