Description
Input
第一行给出两个整数N,M。分别表示序列长度和操作个数
接下来一行有N个数,即给定的序列a1,a2,….an
接下来M行,每行对应一个操作,格式见题目描述
Output
对于每个询问操作,输出一行,表示所询问的SSi的值。
Sample Input
5 3
1 2 3 4 5
Query 5
Modify 3 2
Query 5
Sample Output
35
32
HINT
1<=N,M<=100000,且在任意时刻0<=Ai<=100000
Source
Katharon+#1
考虑使用两个数的差来得到答案.
建两个BIT维护一下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXN 100100
#define lowbit(x) (x&(-x))
#define LL long long
#define GET (ch>='0'&&ch<='9')
using namespace std;
int n,m,a[MAXN],x,y;
char s[10];
struct BIT
{
LL C[MAXN];
void add(int x,LL delta)
{
for (int i=x;i<=n;i+=lowbit(i)) C[i]+=delta;
}
LL query(int x)
{
LL ret=0;
for (int i=x;i;i-=lowbit(i)) ret+=C[i];
return ret;
}
}s1,s2;
void in(int &x)
{
char ch=getchar();x=0;
while (!GET) ch=getchar();
while (GET) x=x*10+ch-'0',ch=getchar();
}
int main()
{
in(n);in(m);
for (int i=1;i<=n;i++) in(a[i]),s1.add(i,a[i]),s2.add(i,(LL)(n-i+1)*a[i]);
for (int i=1;i<=m;i++)
{
scanf("%s",s);
if (s[0]=='M') in(x),in(y),s1.add(x,y-a[x]),s2.add(x,(LL)(n-x+1)*(y-a[x])),a[x]=y;
else in(x),printf("%lld\n",s2.query(x)-s1.query(x)*(n-x));
}
}