我们考虑把一个数字加某个值
a1 a2 a3 a4 a5a6
+t
s1 s2 s3s4 s5 s6
+t +t+t +t
ss1 ss2 ss3 ss4 ss5 ss6
+t +2t+3t +4t
设d[i]表示从i开始ss[i]依次加d[i],d[i]*2,d[i]*3....
d[i]对于ss[n]的贡献为d[i]*(n-i+1)
设原数组为org
ss[n] = sigma(org[i]) + sigma(d[i]*(n-i+1))
=sigma(org[i]) + sigma(d[i])*(n+1) - sigma(d[i]*i)
用树状数组维护d[i]和的d[i]*i即可
#include <stdio.h>
#define MAXN 100003
int n, Q;
int a[MAXN], d[MAXN];
int lowbit(int x)
{
return x & (-x);
}
void plus(long long *f, int p, long long x)
{
int i;
for (i = p; i <= n; i += lowbit(i))
f[i] += x;
}
long long query(long long *f, int p)
{
long long ans = 0;
int i;
for (i = p; i; i -= lowbit(i))
ans += f[i];
return ans;
}
long long s[MAXN], d0[MAXN], d1[MAXN];
int main()
{
scanf("%d%d", &n, &Q);
int i;
long long tmp = 0;
for (i = 1; i <= n; ++i)
{
scanf("%d", &a[i]);
s[i] = s[i - 1] + (tmp += a[i]);
}
while (Q--)
{
char opt[10];
scanf("%s", opt);
if (opt[0] == 'Q')
{
int p;
scanf("%d", &p);
long long ans = s[p];
ans += query(d0, p) * (p + 1);
ans -= query(d1, p);
#ifdef ONLINE_JUDGE
printf("%lld\n", ans);
#else
printf("%I64d\n", ans);
#endif
}
else
{
int p, x;
scanf("%d%d", &p, &x);
long long t = x - a[p];
plus(d0, p, t);
plus(d1, p, t * p);
d[p] += t;
a[p] = x;
}
}
return 0;
}