【模板】树状数组
来源:互联网 发布:mysql注入式攻击 编辑:程序博客网 时间:2024/06/15 05:03
树状数组可以解决什么样的问题
对于包含n个元素的整数数组a,每次可以
1. C(i, j): 修改一个元素a[i] = j
2. Q(i): 询问前缀Si=a1+a2+…+ai的值
lowbit值
在说树状数组之前,我们不得不说一下lowbit值
设c[i]=a[i-2k+1]+…+a[i],其中k为i在二进制下末尾0的个数
令LOWBIT(i)=2^k
例如, i=1001010110010000, 则k=4
因为补码的原理是:正数变负数时,按位取反 末位加一
所以对于正数x 我们不难得到lowbit公式: lowbit(x)=x and -x
树状数组是一个动态维护前缀和的数据结构
网上最“火”的图应该是这个
修改操作
当修改c[x]时, 可能有很多c随之修改
例如,对于x=76=01001010,可以得到:
p1= 01001010
p2= 01001100
p3= 01010000
p4= 01100000
p5= 10000000
所以
•P1=x
•Pi+1=Pi+LOWBIT(Pi)
则需要依次修改C[p1],C[p2],…
询问操作
如何计算A[1]+…+A[x]?
首先累加C[x], 因为它的定义是以x结尾的连续和,它的连加起点是C[i-LOWBIT(i)+1]
因此问题转化为了求A[1]+…+A[i-LOWBIT(i)]
由此, 我们得到递推式
•P1=x
•Pi+1=Pi-LOWBIT(Pi)
则只需要累加C[p1], C[p2], …
清晰一点就像这样
【模板】树状数组 1 洛谷P3374
裸树状数组代码:
#include<bits/stdc++.h>#define lowbit(x) (x&(-x))#define MAXN 500050using namespace std;int tree[MAXN];int n,m;inline void add(int x,int num){ while(x<=n) { tree[x]+=num; x+=lowbit(x); }}inline int search(int x){ int re=0; while(x) { re+=tree[x]; x-=lowbit(x); } return re;}int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) { int x; scanf("%d",&x); add(i,x); } for(int i=1;i<=m;++i) { int opt,x,y; scanf("%d%d%d",&opt,&x,&y); if(opt==1) add(x,y); else printf("%d\n",search(y)-search(x-1)); } return 0;}
【模板】树状数组 2 洛谷P3368
裸树状数组+差分
#include<bits/stdc++.h>#define lowbit(x) (x&(-x))#define MAXN 500050using namespace std;int tree[MAXN];int a[MAXN];int n,m;inline void add(int x,int num){ for(int i=x;i<=n;i+=i&-i) { tree[i]+=num; }}inline int search(int x){ int re=0; while(x) { re+=tree[x]; x-=lowbit(x); } return re;}int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) scanf("%d",&a[i]),add(i,a[i]-a[i-1]); for(int i=1;i<=m;++i) { int opt,x,y,k; scanf("%d",&opt); if(opt==1) { scanf("%d%d%d",&x,&y,&k); add(y+1,-k); add(x,k); } else { scanf("%d",&x); printf("%d\n",search(x)); } } return 0;}
阅读全文
2 2
- 树状数组【模板】
- 树状数组模板
- 树状数组 模板
- 树状数组模板
- 树状数组模板
- 树状数组-模板
- 树状数组模板
- 树状数组模板
- 树状数组模板
- 树状数组--模板
- 树状数组模板
- 模板 树状数组
- 模板,树状数组
- 树状数组(模板)
- 树状数组模板
- 树状数组的模板;
- 树状数组 (模板)
- 树状数组BIT 模板
- 数据库——事务隔离级别的理解
- 0.ROS 安装与配置
- bzoj 1588: [HNOI2002]营业额统计 spaly
- ECNUSUM4 J hdu5652India and China Origins
- kafka入门:简介、使用场景、设计原理、主要配置及集群搭建(转)
- 【模板】树状数组
- POJ2240-Arbitrage-C语言&&NYOJ-188
- python函数参数中*args,**kwargs的使用和意义
- codeforces 632E(FFT+分治)
- PHP进阶(第八弹:函数)
- The first csdn blog
- 逆矩阵模板 #线性代数
- SQL--子查询
- 谈谈数据库连接池的原理