[文章目录]
Description
前缀和的前缀和???这不是我考试题吗??还没有区间修改区间查询???水过。
其实就是化简一下:
维护两颗线段树就好了啊???
还是前缀和,没有区间修改,两个树状数组就好了啊。
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100100
using namespace std;
typedef long long ll;
ll f1[N],f2[N],s1[N],s2[N];
int w[N],n,m;
inline int read()
{
char ch=getchar(); int re=0;
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9')
re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
return re;
}
inline void fix(int x,ll y,ll z) {while(x<=n) f1[x]+=y,f2[x]+=z,x+=-x&x;}
inline void Query()
{
int x,y; y=x=read(); ll ans=s1[x];
while(y>0) ans+=f1[y],y-=-y&y; ans=ans*(x+1);
ans-=s2[x]; y=x; while(y>0) ans-=f2[y],y-=-y&y;
printf("%lld\n",ans);
}
inline void Fix()
{
int x,y; x=read(); y=read();
fix(x,y-w[x],(ll)(y-w[x])*x);
w[x]=y;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
{
w[i]=read();
s1[i]=s1[i-1]+w[i];
s2[i]=s2[i-1]+(ll)w[i]*i;
}
char sw[30];
while(m--)
{
scanf("%s",sw);
if(sw[0]=='Q') Query();
else Fix();
}
return 0;
}