算法日记13:SC41树状数组(区间修改)

ops/2025/2/7 13:36:19/

一、题目:

在这里插入图片描述

二、题解:

在单点修改中,我们用t[i]来维护原数组

2.1:在区间修改中,我们将维护原数组的差分数组

  • 接下来,让我们来回顾一些差分的性质
    在这里插入图片描述
  • 此时,假设我们需要求 a 1 + a 2 + a 3 + a 4 a1+a2+a3+a4 a1+a2+a3+a4的和,并且是直接通过 d [ i ] d[i] d[i]来求,我们可以发现:
    在这里插入图片描述
  • 推广到 n n n可以得到
    在这里插入图片描述

2.2:因此我们可以维护两个数组,一个为 t d [ i ] td[i] td[i](PS:因为n+1是常量),一个为 i ∗ t d [ i ] i*td[i] itd[i],这样就可以直接通过 d [ i ] d[i] d[i]来进行区间查询

  • t d [ i ] td[i] td[i]表示的是: d [ i ] d[i] d[i] [ i − l o w b i t ( i ) + 1 , i ] [i-lowbit(i)+1,i] [ilowbit(i)+1,i]的值(PS:相当于差分时,对差分数组做前缀和映射到原数组)
    在这里插入图片描述

2.3:相较于单点修改的差别

1、变量定义:

ll td[N];  //维护树状数组的差分
ll tdi[N]; //维护td[i]*i

2、更新树状数组–>更新树状差分数组单点修改(相当于在 i i i + a [ i ] +a[i] +a[i])

	//初始化树状差分数组for (int i = 1; i <= n; i++) {update(i, a[i]);update(i+1,-a[i]);}

3、对于操作1(区间修改)变化:运用差分性质( ( a [ l ] − > a [ r ] ) + v = = ( d [ l ] + v ) , d [ r + 1 ] − v (a[l]->a[r])+v==(d[l]+v),d[r+1]-v (a[l]>a[r])+v==(d[l]+v),d[r+1]v)

		int op; cin >> op;if (op == 1){ll l, r , v; cin >> l >> r >> v;update(l, v);   //维护差分数组update(r+1,-v);}

4、 u p d a t e ( ) update() update()更新函数的变化:

  • 1):与单点修改思路一致,差分数组( t d [ i ] td[i] td[i])对于其每一个数字的管辖区间 + v +v +v
  • 2):对于 t d i [ i ] tdi[i] tdi[i],也就是 i ∗ t d [ i ] i*td[i] itd[i],每一个元素都应该 + + +传入函数的原始值 ( x ∗ v ) (x*v) xv如图:而不应该 ( i ∗ v ) (i*v) (iv)因为此时 t d i [ x ] tdi[x] tdi[x]的增加影响了 t d i [ i ] tdi[i] tdi[i]的值如果写成了 ( i ∗ v ) (i*v) (iv)就变成了 ( 4 ∗ 2 ) (4*2) 42,但是实际应该为 ( 3 ∗ 2 ) (3*2) (32)
    在这里插入图片描述
void update(ll x, ll v)   //第 x 个值变化了 v
{for (int i = x; i <= n; i += lowbit(i)){td[i] += v; //维护tdtdi[i]+=x*v; //维护td*i}
}

5、 g e t s u m ( ) getsum() getsum()求和函数的变化

  • 1、由推广公式可以得到求和函数
  • 2、类比前缀和的性质,求解 g e t s u m ( r ) − g e t s u m ( l − 1 ) getsum(r) - getsum(l - 1) getsum(r)getsum(l1)即可得出 [ l , r ] [l,r] [l,r]的和
    在这里插入图片描述
ll getsum(ll x)   //区间查询
{ll sum = 0;for (int i = x; i >= 1; i-=lowbit(i)){sum += (x+1)*td[i]-tdi[i];}return sum;
}
ll l, r; cin >> l >> r;
cout << getsum(r) - getsum(l - 1) << '\n';

三、完整代码如下:

#include <bits/stdc++.h>
using namespace std;typedef long long ll;
const int N = 3e5 + 7;
ll a[N];
ll td[N];  //维护树状数组的差分
ll tdi[N]; //维护td[i]*i
ll n, q;ll lowbit(ll x)   //树状数组底层函数
{return x & -x;
}void update(ll x, ll v)   //第 x 个值变化了 v
{for (int i = x; i <= n; i += lowbit(i)){td[i] += v; //维护tdtdi[i]+=x*v; //维护td*i}
}ll getsum(ll x)   //区间查询
{ll sum = 0;for (int i = x; i >= 1; i-=lowbit(i)){sum += (x+1)*td[i]-tdi[i];	//求和公式}return sum;
}void solve()
{cin >> n >> q ;for (int i = 1; i <= n; i++) cin >> a[i];//初始化树状数组for (int i = 1; i <= n; i++) {update(i, a[i]);update(i+1,-a[i]);}while (q--) //q次询问{int op; cin >> op;if (op == 1){ll l, r , v; cin >> l >> r >> v;update(l, v);   //维护差分数组update(r+1,-v);}else{ll l, r; cin >> l >> r;cout << getsum(r) - getsum(l - 1) << '\n';}}
}int main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int _ = 1; //cin >> _;while (_--) solve();system("pause");return 0;
}

http://www.ppmy.cn/ops/156444.html

相关文章

7.4状压DP

在C中&#xff0c;状态压缩动态规划&#xff08;State Compression DP&#xff0c;简称状压DP&#xff09; 是一种通过 二进制位运算 高效表示离散状态集合的动态规划方法&#xff0c;特别适用于解决 组合优化 和 排列选择 类问题。其核心思想是将多维状态压缩为整数&#xff0…

项目练习:SpringSecurity+OAuth2接入gitee的第三方登陆(授权码模式)

文章目录 一、知识准备1、OAuth2的角色2、使用场景3、四种授权模式 二、案例实现1、gitee上注册应用2、直接通过手动发送http请求方式3、项目代码方式4、测试方法 一、知识准备 1、OAuth2的角色 1、资源所有者(Resource 0wner):即用户&#xff0c;资源的拥有人&#xff0c;想要…

Spring Boot Actuator与JMX集成实战

在微服务架构中&#xff0c;监控和管理应用的运行状态是至关重要的。Spring Boot Actuator 提供了一种便捷的方式来监控和管理 Spring Boot 应用&#xff0c;而 JMX&#xff08;Java Management Extensions&#xff09;则是一种用于管理 Java 应用的标准技术。本文将通过一个实…

大语言模型极速部署:Ollama 、 One-API、OpenWebUi 完美搭建教程

大语言模型极速部署&#xff1a;Ollama 、 One-API、OpenWebUi 完美搭建教程 本文将介绍如何通过命令行工具部署 Ollama 和 One-API 以及 OpenWebUi&#xff0c;帮助你快速搭建私有化大模型。 Ollama 是一个容器化工具&#xff0c;简化了大语言模型的管理与运行&#xff0c;支持…

TongSearch3.0.4.0安装和使用指引(by lqw)

文章目录 安装准备手册说明支持的数据类型安装控制台安装单节点(如需集群请跳过这一节)解压和启动开启X-Pack Security和生成p12证书&#xff08;之后配置内置密码和ssl要用到&#xff09;配置内置用户密码配置ssl&#xff08;先配置内置用户密码再配ssl&#xff09;配置控制台…

linux环境自动化golang项目启动脚本解析

一.场景介绍 当在本地创建了golang项目,修改了代码功能,怎么在远程测试服务器上更新该功能呢,可以使用下面的步骤来解决该问题(这只是其中一种方法): (1).推送最新代码到远程仓库 (2).在测试服务器上创建该项目并拉取最新代码 (3).创建deploy.sh脚本 (4).运行deploy.sh脚本 二.…

deepseek接入pycharm 进行AI编程

要将DeepSeek接入PyCharm进行AI编程,可以按照以下步骤操作: ### 1. 获取DeepSeek API访问权限 DeepSeek通常以API的形式对外提供服务,你需要在其官方网站注册账号,申请API访问权限。在申请通过后,会获得API密钥(API Key),这是后续调用API的关键凭证。 ### 2. 安装必要…

游戏引擎 Unity - Unity 下载与安装

Unity Unity 首次发布于 2005 年&#xff0c;属于 Unity Technologies Unity 使用的开发技术有&#xff1a;C# Unity 的适用平台&#xff1a;PC、主机、移动设备、VR / AR、Web 等 Unity 的适用领域&#xff1a;开发中等画质中小型项目 Unity 适合初学者或需要快速上手的开…