树状数组 区间加 区间求和_支持区间修改的树状数组


layout: posttitle: 支持区间修改的树状数组 |oyxBlogcategories: [树状数组, 模板]description: 树状数组的变种keywords: 树状数组, 模板

原理

对于一个数组

,以及
的差分
,显然有

那么对于数组a的前缀和有

进一步的:

展开括号内

即为

因此维护一个前缀和数组需要维护两个差分前缀和

,对应为维护

这里使用两个树状数组对上述差分数组前缀和维护,分别命名为

实现

首先明确基本树状数组的两个基本操作:区间查询单调查询。使用树状数组维护前缀和:

  1. 区间查询
    ,1到k之间的前缀和
  2. 单点修改
    ,

那么对于本文中的支持区间修改的树状数组有以下操作:1.区间修改

(l和r包含),等效于操作
,
,
(差分性质定义)2.区间查询 ,
,等效于操作

操作

基本树状数组

实现了

单点修改和区间查询。支持单点修改,区间查询,单点查询。
int 

初始化

void 

区间修改

//[l,r]区间修改+xvoid add(int l, int r, int x) {  add(tr, l, x);  add(tr, r + 1, -x);  add(tr1, l, 1ll * (l - 1) * x);  add(tr1, r + 1, 1ll * r * (-x));}

区间查询

查询

,即查询
内的前缀和
//区间查询原数组sum(a[1,k])ll querysum(int k) {  return (1ll * query(tr, k) * k)  - query(tr1, k);}

区间修改

区间加上
.
//[l,r]区间修改+xvoid add(int l, int r, int x) {  add(tr, l, x);  add(tr, r + 1, -x);  add(tr1, l, 1ll * (l - 1) * x);//防止暴int  add(tr1, r + 1, 1ll * r * (-x));}

复杂度分析

实质是两个树状数组来维护着差分前缀和,其中空间是3倍的区间长度,

时间复杂度:在以下操作均为
  • 区间同加x
  • 区间查询
  • 单点查询
  • 单调同加x

相比线段树空间复杂度

要小时间复杂度相同。

编程复杂度差不多(都好难orz)

整合模板

题目传送门

#define judge

参考链接:树状数组区间加等差数列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值