树状数组求调
查看原帖
树状数组求调
1053122
shy_lihui楼主2024/11/25 01:39
#include<bits/stdc++.h>
using namespace std;
int n,m;
int At[1000005];
int Bt[1000005];
int lowbit(int x)
{
    return x&(-x);
}
void Aadd(int pos,int x)
{
    while(pos<=n)
	{
        At[pos]+=x;
        pos+=lowbit(pos);
    }
}
int Asum(int pos)
{
    int cnt=0;
    while(pos>0)
	{
        cnt+=At[pos];
        pos-=lowbit(pos);
    }
    return cnt;
}

void Badd(int pos,int x)
{
    while(pos<=n)
	{
        Bt[pos]+=x;
        pos+=lowbit(pos);
    }
}
int Bsum(int pos)
{
    int cnt=0;
    while(pos>0)
	{
        cnt+=Bt[pos];
        pos-=lowbit(pos);
    }
    return cnt;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		int x;
		cin>>x;
		Aadd(i,x);
		Aadd(i+1,-x);
		Badd(i,x*i);
		Badd(i+1,-(x*i));
	}
	while(m--)
	{
		int q;
		cin>>q;
		if(q==1)
		{
			int x,y,k;
			cin>>x>>y>>k;
			Aadd(x,k);
			Aadd(y+1,-k);
			Badd(x,k*x);
			Badd(y+1,-(k*y));
		}
		else
		{
			int x,y;
			cin>>x>>y;
			cout<<((y+1)*Asum(y)-Bsum(y))-((x+1)*Asum(x)-Bsum(x))<<'\n';
		}
	}
	return 0;
}

设原始数组为 aa,树状数组为 bb

那么

i=1xai=i=11bi+i=12bi+i=13bi+i=1xbi=b1×x+b2×(x1)+b3×(x2)++bx×1=(x+1)i=1xdi1×d12×d2++x×dx=(x+1)i=1xdii=1x(i×di)\begin{aligned} \sum_{i=1}^{x} a_i &= \sum_{i=1}^{1} b_i + \sum_{i=1}^{2} b_i + \sum_{i=1}^{3} b_i + \cdots \sum_{i=1}^{x} b_i \\ &= b_1 \times x + b_2 \times (x-1) + b_3 \times (x-2) + \cdots + b_x \times 1 \\ &= (x+1) \sum_{i=1}^{x} d_i - 1 \times d_1 -2 \times d_2 + \cdots + x \times d_x \\ &= (x+1) \sum_{i=1}^{x} d_i - \sum_{i=1}^{x} (i \times d_i) \end{aligned}
2024/11/25 01:39
加载中...