BZOJ-3155: Preprefix sum

[文章目录]

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;
}

发表评论

邮箱地址不会被公开。 必填项已用*标注