3155: Preprefix sum

传说可以用树状数组,不过因为本人比较菜,于是上无脑差分数组+线段树。

容易发现,当一个数i增加x时,会使前缀和的前缀和j(j>=i)增加(j-i+1)*x。那么可以想象成i~n段加x,i+1~n段加x,i+2~n段加x……。

那么用差分数组就可以直接改i~n,然后可以求前缀和求答案。(前缀和的前缀和的差分前缀和?有点绕)

具体还是代码吧。语文死的早。

code:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#define LL long long
using namespace std;
struct node{
	int l,r,lc,rc;
	LL c,u;
}tr[200010];int trlen=0;
int n,m,a[100010];
LL sum[100010];
int bt(int l,int r)
{
	int x=++trlen;
	tr[x].l=l;tr[x].r=r;tr[x].c=0;tr[x].u=0;
	if(l!=r)
	{
		int mid=(l+r)/2;
		tr[x].lc=bt(l,mid);
		tr[x].rc=bt(mid+1,r);
	}
	return x;
}
void update(int x)
{
	int lc=tr[x].lc,rc=tr[x].rc;LL u=tr[x].u;
	tr[lc].c+=u*(LL)(tr[lc].r-tr[lc].l+1);
	tr[rc].c+=u*(LL)(tr[rc].r-tr[rc].l+1);
	tr[lc].u+=u;tr[rc].u+=u;
	tr[x].u=0;
}
void change(int x,int l,int r,LL c)
{
	if(tr[x].l==l&&tr[x].r==r)
	{
		tr[x].u+=c;
		tr[x].c+=c*(r-l+1);return;
	}
	int mid=(tr[x].l+tr[x].r)/2,lc=tr[x].lc,rc=tr[x].rc;
	if(tr[x].u!=0) update(x);
	if(r<=mid) change(lc,l,r,c);
	else if(l>mid) change(rc,l,r,c);
	else change(lc,l,mid,c),change(rc,mid+1,r,c);
	tr[x].c=tr[lc].c+tr[rc].c;
}
LL findans(int x,int l,int r)
{
	if(tr[x].l==l&&tr[x].r==r) return tr[x].c;
	int mid=(tr[x].l+tr[x].r)/2,lc=tr[x].lc,rc=tr[x].rc;
	if(tr[x].u!=0) update(x);
	if(r<=mid) return findans(lc,l,r);
	if(l>mid) return findans(rc,l,r);
	return findans(lc,l,mid)+findans(rc,mid+1,r);
}
int main()
{
	scanf("%d %d",&n,&m);a[0]=0;
	for(int i=1;i<=n;i++) scanf("%d",&a[i]),sum[i]=(LL)a[i];
	for(int i=1;i<=n;i++) sum[i]+=sum[i-1];
	for(int i=1;i<=n;i++) sum[i]+=sum[i-1];
	bt(1,n);change(1,1,1,sum[1]);
	for(int i=2;i<=n;i++) change(1,i,i,sum[i]-sum[i-1]);
	char s[5];
	while(m--)
	{
		scanf("%s",s+1);int x,y;
		scanf("%d",&x);
		if(s[1]=='M') scanf("%d",&y),change(1,x,n,(LL)(y-a[x])),a[x]=y;
		else printf("%lld\n",findans(1,1,x));
	} 
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值