zoukankan      html  css  js  c++  java
  • 树状数组区间修改加区间查询

    其实之前在K大数查询中就已经用到了,只是一直没有说明
    所以今天就来补个欠账。
    感觉单点修改、区间查询和区间修改、单点查询没什么必要讲,这里就只讲区间修改、区间查询(其实也不难)。
    设原数组第(i)位的值为(a_i)(d_i=a_i-a_{i-1}),则有(这里认为(a_0=0)):

    [a_x=sum_{i=1}^x d_i ]

    所以有:

    [sum_{i=1}^x a_i= sum_{i=1}^x sum_{j=1}^i d_j =sum_{i=1}^x(x-i+1)d_i ]

    于是我们得到了:

    [sum_{i=1}^x a_i=(x+1)sum_{i=1}^x d_i-sum_{i=1}^x d_i imes i ]

    于是我们把原数组差分后维护两个树状数组,一个维护(d_i),一个维护(d_i imes i)
    这样区间求和时可以在两个树状数组中查询得到前缀和,区间修改时就是差分数组的修改,每次修改两个点即可。
    具体代码如下:

    void add(int x,int y){for(int i=x;i<=n;i+=i&(-i)) c1[i]+=y,c2[i]+=(long long)x*y;}//给差分数组中的位置x加上y
    long long sum(int x){//查询前x项的和
        long long ans(0);
        for(int i=x;i;i-=i&(-i)) ans+=(x+1)*c1[i]-c2[i];
        return ans;
    }
    

    其中(c{1_i})维护的是(d_i)(c{2_i})维护的是(d_i imes i)
    比线段树好写多了是不?

  • 相关阅读:
    个人项目作业
    自我介绍+软工五问
    Word Count
    个人简介+软工五问
    小学生算术题生成器
    个人项目-WC
    个人简历+软工五问
    学习有感
    学习爱我
    软件工程学习记录
  • 原文地址:https://www.cnblogs.com/lcf-2000/p/5866170.html
Copyright © 2011-2022 走看看