首页 > 其他分享 >树状数组区间修改区间查询

树状数组区间修改区间查询

时间:2024-02-13 14:55:06浏览次数:35  
标签:树状 int sum update 数组 区间 query

树状数组区间修改区间查询

问题——两种操作

  1. 给定 \(l,r,x\) ,将 \([l,r]\) 这个区间内的所有值都加上 \(x\)
  2. 给定 \(l,r\) 求出 \([l,r]\) 的区间和

这道题肯定要用前缀和和差分,那么大体框架可以出来了

//操作一:
update(l, x), update(r + 1, -x);
//操作二
query(r) - query(l - 1)

那么怎么将这两个东西串在一起呢?

设 \(a\) 为原数组,\(sum\) 为前缀和数组,则:

\[sum_k=\sum_{i=1}^{k}a_i \]

再设 \(b\) 为差分数组,根据定义,易得:

\[a_k=\sum_{i=1}^{k}b_i \]

放在一起可以得到:

\[sum_k=\sum_{i=1}^{k}\sum_{j=1}^{i}b_j \]

可以发现 \(b_1\) 被使用了 \(k\) 次, \(b_2\) 被使用了 \(k-1\) 次,可以发现,对于 \(sum_k\) , \(b_i\) 被用了 \(k-i+1\) 次,所以可以把原式转化成:

\[sum_k=\sum_{i=1}^{k}b_i\times(k-i+1) \]

由于 \(k+1\) 对原来的式子没有任何影响,可以提取出来,这样再转化得

\[sum_k=(k+1)\sum_{i=1}^kb_i-\sum_{i=1}^kb_i\times i \]

这样我们只要分别维护 \(b_i\) 和 \(b_i \times i\) 的前缀和就可以了

对于 \(\text{update}\)

void update(int x, int k)
{
    for(int i = x; i <= n; i += lowbit(i))
        tr1[i] += k, tr2[i] += k * x; 
}

对于 \(\text{query}\)

ll query(int x)
{
    ll ans = 0;
    for(int i = x; i; i -= lowbit(i))
       	ans += tr1[i] * (x + 1) - tr2[i];
   	return ans;
}

标签:树状,int,sum,update,数组,区间,query
From: https://www.cnblogs.com/ljfyyds/p/18014597

相关文章

  • 区间满足条件的子区间计数
    区间满足条件的子区间计数一般是扫描线,可能会有线段树维护历史版本信息。CF526FPuddingMonsters题意:给定一个\(n\timesn\)的棋盘,其中有\(n\)个棋子,每行每列恰好有一个棋子。对于所有的\(1\leqk\leqn\),求有多少个\(k\timesk\)的子棋盘中恰好有\(k\)个棋子。......
  • Suffix Array:后缀数组学习笔记
    后缀排序后缀排序,顾名思义就是给后缀排个序。朴素做法是\(O(n^2\logn)\)的,无法接受。因此诞生了基于倍增思想的后缀排序算法。其中倍增思想在集训队论文中讲得很好,在此不再赘述。这里主要讲代码实现。constintN=2e6+10;chars[N];intn,m,sa[N],rk[N],tp[N],b[N];void......
  • 数状数组
    介绍树状数组主要操作为lowbit函数(取出x元素的低位二次幂)方便用于爬链操作(每层子节点通过加上低位二次幂可到达父节点),以及求前缀序列和的操作(将x减去其低位二次幂可得到前一未覆盖序列,通过累加从而达到求前缀和的操作)。点击查看代码intlowbit(intx){returnx&-x;}适用......
  • 连续性区间位置查询——链式并查集
    目录问题概述思路分析参考代码做题总结问题概述这里给出两个题目,一个是上一篇的新春漫步(其实当时给的官方题解就是链式并查集的写法,但是当时我懒得写了,emmm),二是最近vp的一场cf_div3_923场的d题,准确来说,就是因为这个我才准备写这个的,题目大概就是给出一个长度为n的数组和q组询......
  • Linux 中 使用awk数组根据基因的PAV矩阵计算基因的存在频率
     001、测试数据[b20223040323@admin1test]$lsx_gather_pav.txt[b20223040323@admin1test]$catx_gather_pav.txt##测试数据;每一行是一个个体;每一列是一个基因;矩阵中的0表示基因在这个个体中缺失,1表示基因在这个个体中存在01111......
  • Linux 中 字符串 与shell数组的转换
     001、字符串转换为shell数组[root@PC1test1]#str1="aabb100200500"##生成测试字符串[root@PC1test1]#echo$str1aabb100200500[root@PC1test1]#ay1=($str1)##字符串转换为数组[root@PC1test1]#echo${ay1[0]}......
  • POJ--1179 Polygon(区间DP)
    记录22:012024-2-10http://poj.org/problem?id=1179区间DP问题。区间DP问题可能需要注意的点就是是根据区间长度来计算的,随着迭代区间长度不断增加,结果也就计算出来了这种“任意选择一个位置断开,复制形成2倍长度的链”的方法,是解决DP中环形结构的常用手段之一因此读入数......
  • Java break、continue 详解与数组深入解析:单维数组和多维数组详细教程
    JavaBreak和ContinueJavaBreak:break语句用于跳出循环或switch语句。在循环中使用break语句可以立即终止循环,并继续执行循环后面的代码。在switch语句中使用break语句可以跳出当前case,并继续执行下一个case。示例://循环示例for(inti=0;i<10;i++......
  • 力扣递归之88. 合并两个有序数组
    给你两个按非递减顺序排列的整数数组 nums1和nums2,另有两个整数m和n,分别表示nums1和nums2中的元素数目。请你合并nums2到nums1中,使合并后的数组同样按非递减顺序排列。注意:最终,合并后数组不应由函数返回,而是存储在数组nums1中。为了应对这种情况,nums1的初......
  • 面向对象综合练习-对象数组5
    ......