zoukankan      html  css  js  c++  java
  • [BZOJ 3155] Preprefix sum

    Link:

    BZOJ 3155 传送门

    Solution:

    我们发现要维护的序列的每一项都有$i$项要维护,

    我们要将每一项转化为只有1项要维护才能$log(n)$维护(否则每对一个值更新要更新$n$个值)

    于是我们将每一项拆为两个前缀和相减,

    开两个树状数组,第一个维护$a[i]$前缀和,第二个维护$(n-i+1)*a[i]$的前缀和

    $res=BIT2[x]-BIT1[x]*(n-x)$

    Code:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int MAXN=1e5+10;
    typedef long long ll;
    char op[10];
    ll bit[2][MAXN];
    int dat[MAXN],n,m,x,y;
    
    void Update(int f,int pos,ll val){while(pos<=n) bit[f][pos]+=val,pos+=pos&(-pos);}
    ll Query(int f,int pos)
    {
        ll ret=0;
        while(pos){ret+=bit[f][pos];pos-=pos&(-pos);}
        return ret;
    } 
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&dat[i]),Update(0,i,dat[i]),Update(1,i,1ll*dat[i]*(n+1-i));
        while(m--)
        {
            scanf("%s",op);
            if(op[0]=='Q')
                scanf("%d",&x),
                printf("%lld
    ",Query(1,x)-1ll*Query(0,x)*(n-x));
            else
                scanf("%d%d",&x,&y),
                Update(0,x,y-dat[x]),Update(1,x,1ll*(n-x+1)*(y-dat[x])),dat[x]=y;
        }
        return 0;
    }

    Review:

    观察到数据中系数的递减,从而将每项构造为两个前缀和的差

  • 相关阅读:
    简单图片预加载
    前端进行图片压缩
    原生js实现拖动滑块验证
    chrome和IE下的滚动条样式修改
    简单canvas刮刮乐
    时间轴
    简单边框动画
    滚动指示器
    美化checkbox多选框
    将过长的文字改用省略号显示
  • 原文地址:https://www.cnblogs.com/newera/p/9127071.html
Copyright © 2011-2022 走看看