• [bzoj 3155] Preprefix sum(树状数组) 2017-05-25 15:10 29人阅读 评论(0) 收藏


    传送门

    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

    思路

    学过线段树都知道树状数组不能处理区间修改,无逆元的区间加法
    但是树状数组其实用差分可以做区间修改单点查询
    当然这道题和更强的区间修改求和关系不大,但形式确实很像
    对于原数列a1,a2,a3,a4…
    a为 a1,a2,a3,a4…
    S为 1*a1, 1*a1+1*a2, 1*a1+1*a2+1*a3…
    SS为1*a1, 2*a1+1*a2, 3*a1+2*a2+1*a3…

    比如 1 2 3 4 5 ,我们要求ss[3]
    我们维护了 cp[3]=1+2+3
    还维护了 cpp[3]=5*1+4*2+3*3
    要 求3*1+2*2+1*3
    就是 cpp[3]-2*cp[3] 2是由5-3得到的 (n-x)
    所以ans=getsum(1,x)-getsum(0,x)*(n-x)

    /**************************************************************
        Problem: 3155
        User: xlj
        Language: C++
        Result: Accepted
        Time:480 ms
        Memory:3240 kb
    ****************************************************************/
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #define ll long long
    using namespace std;
    int n,m;
    ll c[2][100005];
    int a[100005];
    int lowbit(int x){
        return x&(-x);
    }
    void update(int p,int i,ll val){
        for(int x=i;x<=n;x+=lowbit(x))
            c[p][x]+=val;
    }
    ll getsum(int p,int i){
        ll sum=0;
        for(int x=i;x;x-=lowbit(x))
            sum+=c[p][x];
        return sum;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            update(0,i,a[i]);
            update(1,i,(ll)(n-i+1)*a[i]);
        }   
        for(int i=1;i<=m;i++)
        {
            char h[10];
            int x,y;
            scanf("%s",h);
            if(h[0]=='M'){
                scanf("%d%d",&x,&y);
                update(0,x,y-a[x]);
                update(1,x,(ll)(n-x+1)*(y-a[x])); 
                a[x]=y;
             }
             else {
                scanf("%d",&x);
                printf("%lld
    ",getsum(1,x)-getsum(0,x)*(n-x));
             }
        }
        return 0;
    }
  • 相关阅读:
    编译nginx时openssl报错的解决方案
    编译nginx时make报错[-Werror=implicit-fallthrough=]的解决方案
    centos8下编译安装tomcat
    解决centos安装不上apache:No match for argument: httpd
    编译安装apache
    编译apache出现gcc: error: /usr/lib/rpm/redhat/redhat-hardened-ld: No such file or directory
    配置与管理FTP服务器
    2018icpc南京现场赛-I Magic Potion(最大流)
    Codeforces 1062B Math(质因数分解)
    BZOJ 1009 [HNOI2008]GT考试(矩阵快速幂优化DP+KMP)
  • 原文地址:https://www.cnblogs.com/xljxlj/p/7183642.html
Copyright © 2020-2023  润新知