P3368 【模板】树状数组 2 (区间修改,单点查询)

2023-11-29 22:28

本文主要是介绍P3368 【模板】树状数组 2 (区间修改,单点查询),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本题链接:【模板】树状数组 2 - 洛谷

题目:

输入
5 5
1 5 4 2 3
1 2 4 2
2 3
1 1 5 -1
1 3 5 7
2 4
输出
6
10

思路:

        根据题意,这里是需要区间添加值,单点查询值。如果区间添加值中暴力去一个个加值,肯定会TLE,所以我们这里运用到了模板树状数组的重要作用了。

        根据 差分 的性质,我们知道,区间加值,我们可以构造一个前缀和数组来表示当前原数组的元素值,对此,进行区间的修改,有效的避免O(n)的时间复杂度。

所以我们可以结合,树状数组的前缀和 + 差分 性质,达到区间修改,单点查询的效果。

下面给出操作函数:

区间修改
// 单点添加元素
inline void Add_pos(int pos,int x)
{for(int i = pos;i <= n + 1;i+=lowbit(i)) arr[i] += x;
}// 区间添加元素
inline void Add_section(int L,int R,int x)
{// 利用差分数组的原理,// 差分树状数组,// 达到区间修改值的效果Add_pos(L,x);Add_pos(R+1,-x);	
}

单点查询
// 差分前缀和 单点查询
inline int Ask_pos(int pos)
{// 利用 差分 性质// 差分的前缀和,就是当前的元素值// 所以树状数组求前缀和,返回当前下标的元素值int ans = 0;for(int i = pos;i;i-=lowbit(i)) ans += arr[i];return ans;
}

代码详解如下:

#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
#include <unordered_map>
#define endl '\n'
#define int long long
#define YES puts("YES")
#define NO puts("NO")
#define lowbit(x) (x&(-x))
#define umap unordered_map
#define All(x) x.begin(),x.end()
//#pragma GCC optimize(3,"Ofast","inline")
#define IOS std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
using namespace std;
const int N = 7e7 + 10;int n,m;
int arr[N];	// 构造 差分树状数组
int a[N];	// 记录原数组初始值// 单点添加元素
inline void Add_pos(int pos,int x)
{for(int i = pos;i <= n + 1;i+=lowbit(i)) arr[i] += x;
}// 区间添加元素
inline void Add_section(int L,int R,int x)
{// 利用差分数组的原理,// 差分树状数组,// 达到区间修改值的效果Add_pos(L,x);Add_pos(R+1,-x);	
}// 差分前缀和 单点查询
inline int Ask_pos(int pos)
{// 利用 差分 性质// 差分的前缀和,就是当前的元素值// 所以树状数组求前缀和,返回当前下标的元素值int ans = 0;for(int i = pos;i;i-=lowbit(i)) ans += arr[i];return ans;
}inline void solve()
{cin >> n >> m;for(int i = 1;i <= n;++i){cin >> a[i];Add_pos(i,a[i] - a[i - 1]);	// 单点添加 初始值 的 差分元素}while(m--){int op;cin >> op;if(op == 1){int L,R,x;cin >> L >> R >> x;Add_section(L,R,x);	// 区间添加值	}else{int pos;cin >> pos;	// 差分前缀和单点查询cout << Ask_pos(pos) << endl;}}
}signed main()
{
//	freopen("a.txt", "r", stdin);
//	IOS;int _t = 1;
//	cin >> _t;while (_t--){solve();}return 0;
}

最后提交:

这篇关于P3368 【模板】树状数组 2 (区间修改,单点查询)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/434546

相关文章

Security OAuth2 单点登录流程

单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自独立的软件系统,提供访问控制的属性。当拥有这项属性时,当用户登录时,就可以获取所有系统的访问权限,不用对每个单一系统都逐一登录。这项功能通常是以轻型目录访问协议(LDAP)来实现,在服务器上会将用户信息存储到LDAP数据库中。相同的,单一注销(single sign-off)就是指

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

uva 1342 欧拉定理(计算几何模板)

题意: 给几个点,把这几个点用直线连起来,求这些直线把平面分成了几个。 解析: 欧拉定理: 顶点数 + 面数 - 边数= 2。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

uva 11178 计算集合模板题

题意: 求三角形行三个角三等分点射线交出的内三角形坐标。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <