zoukankan      html  css  js  c++  java
  • BZOJ3155: Preprefix sum

    【传送门:BZOJ3155


    简要题意:

      给出一个序列a[i],s[i]表示a[1]到a[i]的和,ss[i]表示s[1]到s[i]的和,对于这个序列有两种操作:

      1.Query x,输出ss[x]

      2.Modify x d,将a[x]改为d


    题解:

      本来想用树状数组,结果写炸了

      还是老老实实写线段树

      将s数组作为叶子节点的值存进线段树,对于第一种操作只需要输出1到x的和就可以了,而第二种操作因为是区间修改,所以用lazy标记来进行继承,对于每次修改,将tr[x].c+=(tr[x].r-tr[x].l+1)*c,这样就能维护值了


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    struct node
    {
        int l,r,lc,rc;LL c;
        LL lazy;
    }tr[210000];int trlen;
    LL a[110000],s[110000];
    void bt(int l,int r)
    {
        trlen++;int now=trlen;
        tr[now].l=l;tr[now].r=r;
        tr[now].lc=tr[now].rc=-1;
        tr[now].lazy=0;
        if(l==r) tr[now].c=s[l];
        else
        {
            int mid=(l+r)/2;
            tr[now].lc=trlen+1;bt(l,mid);
            tr[now].rc=trlen+1;bt(mid+1,r);
            tr[now].c=tr[tr[now].lc].c+tr[tr[now].rc].c;
        }
    }
    void update(int x)
    {
        int lc=tr[x].lc,rc=tr[x].rc;
        if(lc!=-1)
        {
            tr[lc].c+=LL(tr[lc].r-tr[lc].l+1)*tr[x].lazy;
            tr[lc].lazy+=tr[x].lazy;
        }
        if(rc!=-1)
        {
            tr[rc].c+=LL(tr[rc].r-tr[rc].l+1)*tr[x].lazy;
            tr[rc].lazy+=tr[x].lazy;
        }
        tr[x].lazy=0;
    }
    LL getsum(int now,int l,int r)
    {
        if(tr[now].l==l&&tr[now].r==r) return tr[now].c;
        int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2;
        if(tr[now].lazy!=0) update(now);
        if(r<=mid) return getsum(lc,l,r);
        else if(l>mid) return getsum(rc,l,r);
        else return getsum(lc,l,mid)+getsum(rc,mid+1,r);
        tr[now].c=tr[lc].c+tr[rc].c;
    }
    void change(int now,int l,int r,LL c)
    {
        if(tr[now].l==l&&tr[now].r==r)
        {
            tr[now].lazy+=c;
            tr[now].c+=LL(r-l+1)*c;
            return ;
        }
        int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2;
        if(tr[now].lazy!=0) update(now);
        if(r<=mid) change(lc,l,r,c);
        else if(l>mid) change(rc,l,r,c);
        else
        {
            change(lc,l,mid,c);
            change(rc,mid+1,r,c);
        }
        tr[now].c=tr[lc].c+tr[rc].c;
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
        s[0]=0;
        for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
        trlen=0;bt(1,n);
        char st[11];
        for(int i=1;i<=m;i++)
        {
            int x;
            scanf("%s%d",st+1,&x);
            if(st[1]=='Q') printf("%lld
    ",getsum(1,1,x));
            else
            {
                LL d;
                scanf("%lld",&d);
                change(1,x,n,d-a[x]);
                a[x]=d;
            }
        }
        return 0;
    }

     

  • 相关阅读:
    我不想安于当前的限度,以达到所谓的幸福,回顾下2020年的我
    CentOS 7 搭建 TinyProxy 代理 &&python 脚本访问
    使用国内源来安装pytorch速度很快
    opencv-python的格式转换 RGB与BGR互转
    自签SSL证书以及https的双向认证 实现nginx双向代理
    springboot使用 @EnableScheduling、@Scheduled开启定时任务
    微信下载对账单
    SpringBoot 中定时执行注解(@Scheduled、@EnableScheduling)
    使用idea合并 dev分支合并到test分支
    .Net Core + Entity Framework 调用Oracle 存储过程
  • 原文地址:https://www.cnblogs.com/Never-mind/p/8496075.html
Copyright © 2011-2022 走看看