洛谷 P3374【模板】树状数组1、P3368【模板】树状数组2
发布日期:2021-07-01 02:51:07
浏览次数:2
分类:技术文章
本文共 2992 字,大约阅读时间需要 9 分钟。
P3374【模板】树状数组1
题目描述
如题,已知一个数列,你需要进行下面两种操作:- 将某一个数加上 x x x
- 求出某区间每一个数的和
输入格式
第一行包含两个正整数 n , m n,m n,m ,分别表示该数列数字的个数和操作的总个数。第二行包含 n n n 个用空格分隔的整数,其中第 i i i 个数字表示数列第 i i i 项的初始值。接下来 m m m 行每行包含 3 3 3 个整数,表示一个操作,具体如下:
1 x k
含义:将第 x x x 个数加上 k k k2 x y
含义:输出区间 [ x , y ] [x,y] [x,y] 内每个数的和
输出格式
输出包含若干行整数,即为所有操作2
的结果。 输入输出样例
输入 #15 51 5 4 2 31 1 32 2 51 3 -11 4 22 1 4
输出 #1
1416
说明/提示
【数据范围】 对于 30 % 30\% 30% 的数据, 1 ≤ n ≤ 8 , 1 ≤ m ≤ 10 1 \le n \le 8,1\le m \le 10 1≤n≤8,1≤m≤10 ; 对于 70% 的数据, 1 ≤ n , m ≤ 1 0 4 1\le n,m \le 10^4 1≤n,m≤104 ; 对于 100% 的数据, 1 ≤ n , m ≤ 5 × 1 0 5 1\le n,m \le 5\times 10^5 1≤n,m≤5×105 。思路1:使用树状数组,代码如下:
#includeusing namespace std;#define lowbit(x) ((x) & (-x))typedef long long ll;const int MAXN = 5e5 + 10;ll tree[MAXN], n, m, t, a, b;inline void add(ll i, ll d) { while (i <= n) { tree[i] += d; i += lowbit(i); }}inline ll sum(ll i) { ll ret = 0; while (i) { ret += tree[i]; i -= lowbit(i); } return ret;}inline ll query(ll x, ll y) { return sum(y) - sum(x - 1);}int main() { scanf("%lld%lld", &n, &m); memset(tree, 0, sizeof(tree)); for (int i = 1; i <= n; ++i) { scanf("%lld", &t); add(i, t); } for (int i = 1; i <= m; ++i) { scanf("%lld%lld%lld", &t, &a, &b); if (t == 1) add(a, b); else printf("%lld\n", query(a, b)); } return 0;}
P3368【模板】树状数组2
题目描述
如题,已知一个数列,你需要进行下面两种操作:- 将某区间每一个数加上 x x x
- 求出某一个数的值。
输入格式
第一行包含两个整数 N 、 M N、M N、M ,分别表示该数列数字的个数和操作的总个数。 第二行包含 N N N 个用空格分隔的整数,其中第 i i i 个数字表示数列第 i i i 项的初始值。 接下来 M M M 行每行包含 2 2 2 或 4 4 4 个整数,表示一个操作,具体如下: 操作 1 1 1 : 格式:1 x y k
含义:将区间 [ x , y ] [x,y] [x,y] 内每个数加上 k k k ; 操作 2 2 2 : 格式:2 x
含义:输出第 x x x 个数的值。 输出格式
输出包含若干行整数,即为所有操作2
的结果。 输入输出样例
输入 #15 51 5 4 2 31 2 4 22 31 1 5 -11 3 5 72 4
输出 #1
610
说明/提示
数据规模与约定: 对于 30 % 30\% 30% 的数据: N ≤ 8 , M ≤ 10 N\le8,M\le 10 N≤8,M≤10 ; 对于 70 % 70\% 70% 的数据: N ≤ 10000 , M ≤ 10000 N\le 10000,\ M\le 10000 N≤10000, M≤10000 ; 对于 100 % 100\% 100% 的数据: 1 ≤ N , M ≤ 500000 1 \leq N, M\le 500000 1≤N,M≤500000 , 1 ≤ x , y ≤ n 1 \leq x, y \leq n 1≤x,y≤n ,保证任意时刻序列中任意元素的绝对值都不大于 2 30 2^{30} 230 。思路1:使用树状数组的扩展,代码如下:
#includeusing namespace std;#define lowbit(x) ((x) & (-x))typedef long long ll;const int maxn = 5e5 + 10;ll tree[maxn], n, m, k; inline void add(int i, ll d) { while (i <= n) { tree[i] += d; i += lowbit(i); }}inline void addRange(int a, int b, ll c) { //区间修改 add(a, c); add(b + 1, -c);}inline int sum(int i) { //前缀和查询(单点查询) int ret = 0; while (i) { ret += tree[i]; i -= lowbit(i); } return ret;}int main() { scanf("%lld%lld", &n, &m); memset(tree, 0, sizeof(tree)); ll pre = 0, now; for (int i = 1; i <= n; ++i) { scanf("%lld", &now); add(i, now - pre); //维护差分数组 pre = now; } int l, r, op; for (int i = 1; i <= m; ++i) { scanf("%d", &op); if (op == 1) { //把区间[l,r]内的每个数加上k scanf("%d%d%lld", &l, &r, &k); addRange(l, r, k); //区间修改 } else if (op == 2) { //输出第k个数的值 scanf("%d", &k); printf("%lld\n", sum(k)); } } return 0;}
转载地址:https://memcpy0.blog.csdn.net/article/details/108408616 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
不错!
[***.144.177.141]2024年04月22日 23时34分41秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
区块链技术应用,最先医疗行业
2021-07-04
新币上市旧币会降价吗
2021-07-04
当博士进入币圈会怎么样
2021-07-04
PHP之 使用PHPMailer插件实现邮件发送功能
2021-07-04
《增长黑客》(肖恩·艾利斯)学习笔记——第二部分 实战
2021-07-04
python使用HTMLTestRunner查看运行函数
2021-07-04
python的ImportError
2021-07-04
linux下安装jenkins+git+python
2021-07-04
解决uiautomatorviewer中添加xpath的方法
2021-07-04
性能测试的必要性评估以及评估方法
2021-07-04
Spark学习——利用Mleap部署spark pipeline模型
2021-07-04
Oracle创建表,修改表(添加列、修改列、删除列、修改表的名称以及修改列名)
2021-07-04
使用redis实现订阅功能
2021-07-04
对称加密整个过程
2021-07-04
java内存模型
2021-07-04
volatile关键字
2021-07-04
tomcat_关闭
2021-07-04
Servlet_快速入门
2021-07-04
Servlet_生命周期方法
2021-07-04