思路
把公式拆开维护两个值,一个a[i]的总和,一个a[i]*i的总和
也可以用树状数组维护,模板题
代码
#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#define ls rt<<1
#define rs rt<<1|1
#define ll long long
#define FOR(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
const int maxn = 1e5 + 7;
int read() {
int x = 0, f = 1; char s = getchar();
for (; s < '0' || s > '9'; s = getchar()) if (s == '-') f = -1;
for (; s >= '0' && s <= '9'; s = getchar()) x = x * 10 + s - '0';
return x * f;
}
int n,m,a[maxn];
struct node {
int l,r,size;
ll sum1,sum2;
}e[maxn<<2];
void pushup(int rt) {
e[rt].sum1=e[ls].sum1+e[rs].sum1;
e[rt].sum2=e[ls].sum2+e[rs].sum2;
}
void build(int l,int r,int rt) {
e[rt].l=l,e[rt].r=r,e[rt].size=r-l+1;
if(l==r) {
e[rt].sum1=a[l];
e[rt].sum2=a[l]*l;
return;
}
int mid=(l+r)>>1;
build(l,mid,ls);
build(mid+1,r,rs);
pushup(rt);
}
void modfity(int L,int k,int rt) {
if(e[rt].l==e[rt].r) {
e[rt].sum1+=k;
e[rt].sum2=e[rt].sum1*L;
return;
}
int mid=(e[rt].l+e[rt].r)>>1;
if(L<=mid) modfity(L,k,ls);
else modfity(L,k,rs);
pushup(rt);
}
ll query_1(int L,int R,int rt) {
if(L<=e[rt].l&&e[rt].r<=R) {
return e[rt].sum1;
}
int mid=(e[rt].l+e[rt].r)>>1;
ll ans=0;
if(L<=mid) ans+=query_1(L,R,ls);
if(R>mid) ans+=query_1(L,R,rs);
return ans;
}
ll query_2(int L,int R,int rt) {
if(L<=e[rt].l&&e[rt].r<=R) {
return e[rt].sum2;
}
int mid=(e[rt].l+e[rt].r)>>1;
ll ans=0;
if(L<=mid) ans+=query_2(L,R,ls);
if(R>mid) ans+=query_2(L,R,rs);
return ans;
}
int main() {
n=read(),m=read();
FOR(i,1,n) a[i]=read();
build(1,n,1);
FOR(i,1,m) {
int k=read(),x=read(),y=read();
if(k==1) {
modfity(x,y,1);
} else {
ll ans=query_1(x,y,1)*(y+1)-query_2(x,y,1);
printf("%lld
",ans);
}
}
return 0;
}