树状数组和线段树具有相似的功能,但他俩毕竟还有一些区别:树状数组能有的操作,线段树一定有;线段树有的操作,
树状数组不一定有。但是树状数组的代码要比线段树短,思维更清晰,速度也更快,在解决一些单点修改的问题时,树状数组是不二之选。


树状数组 数据结构详解与模板
它的各项操作的时间复杂度均为:O(logn)

常见的模型:

  • 单点修改,区间求和
  • 区间修改,单点求值
  • 区间修改,区间求值
  • 二维树状数组,单点修改,矩阵求值。
  • 二维树状数组, 区间修改 单点查询。
  • 二维树状数组, 区间修改,区间查询。

单点修改,区间求和模板

const int N=1e6+10;
typedef long long int LL;
LL tr[N],n;
int lowbit(int x){return x&(-x);}
void add(int u,int x)//u位置加x
{for(int i=u;i<=n;i+=lowbit(i)) tr[i]+=x;
}
LL query(int u)//求[1,u]的和
{LL sum=0;for(int i=u;i;i-=lowbit(i)) sum+=tr[i];return sum;
}

区间修改,单点求值模板:

//基于差分的思想
const int N=1e6+10;
typedef long long int LL;
LL tr[N],a[N],n,m;
int lowbit(int x){return x&(-x);}
void add(int u,int x)//u位置加x
{for(int i=u;i<=n;i+=lowbit(i)) tr[i]+=x;
}
LL query(int u)//求点u的值
{LL sum=0;for(int i=u;i;i-=lowbit(i)) sum+=tr[i];return sum;
}
void init()//初始化差分数列
{for(int i=1;i<=n;i++) add(i,a[i]-a[i-1]);
}
void solve(int l,int r,int x)//[l,r]加x
{add(l,x),add(r+1,-x);
}

区间修改,区间求值模板:

const int N=1e6+10;
typedef long long int LL;
LL tr1[N],tr2[N],a[N],n,m;
LL lowbit(LL x){return x&(-x);}
void add(LL tr[],LL u,LL c)
{for(int i=u;i<=n;i+=lowbit(i)) tr[i]+=c;
}
LL query(LL tr[],LL u)
{LL sum=0;for(int i=u;i;i-=lowbit(i)) sum+=tr[i];return sum;
}
LL sum(LL u)
{return 1ll*(u+1)*query(tr1,u)-query(tr2,u);
}
void init()//初始化
{for(int i=1;i<=n;i++){add(tr1,i,a[i]-a[i-1]);add(tr2,i,i*(a[i]-a[i-1]));}
}
void add_lr(LL l,LL r,LL c)//[l,r]区间内加c
{add(tr1,l,c),add(tr1,r+1,-c);add(tr2,l,l*c),add(tr2,r+1,-(r+1)*c);
}
LL query_lr(LL l,LL r)//查询区间[l,r]
{return sum(r)-sum(l-1);
}

二维树状数组,单点修改,矩阵求值模板:

const int N=5050;
typedef long long int LL;
LL tr[N][N],n,m;
int lowbit(int x){return x&(-x);}
void add(int x,int y,int v)//[x,y]加v
{for(int i=x;i<=n;i+=lowbit(i))for(int j=y;j<=m;j+=lowbit(j))tr[i][j]+=v;
}
LL query(int x,int y)
{LL sum=0;  for(int i=x;i;i-=lowbit(i))for(int j=y;j;j-=lowbit(j)) sum+=tr[i][j];return sum;
}
LL query_ans(int x,int y,int xx,int yy)
//找[x,y][xx,yy]为左上角和右下角的矩阵的和
{return query(xx,yy)-query(xx,y-1)-query(x-1,yy)+query(x-1,y-1);
}

二维树状数组, 区间修改 单点查询模板:

const int N=5050;
typedef long long int LL;
LL tr[N][N],n,m;
int lowbit(int x){return x&(-x);}
void add(int x,int y,int v)//[x,y]加v
{for(int i=x;i<=n;i+=lowbit(i))for(int j=y;j<=m;j+=lowbit(j))tr[i][j]+=v;
}
LL query(int x,int y)//单点查询
{LL sum=0;  for(int i=x;i;i-=lowbit(i))for(int j=y;j;j-=lowbit(j)) sum+=tr[i][j];return sum;
}
void add1(int x,int y,int xx,int yy,int k)//区间加
{add(x,y,k),add(xx+1,y,-k);add(x,yy+1,-k),add(xx+1,yy+1,k);
}

二维树状数组, 区间修改,区间查询模板:

typedef long long LL;
const int N = 5000 + 10;
LL t1[N][N],t2[N][N],t3[N][N],t4[N][N];
int n,m;
int lowbit(int x) {return x & - x;}
void add(int a, int b, int k)
{for (int i = a; i <= n; i += lowbit(i)) {for (int j = b; j <= m; j += lowbit(j)) {t1[i][j] += k;t2[i][j] += k * a;t3[i][j] += k * b;t4[i][j] += k * a * b;}}
}
LL sum(int a, int b)
{LL ans=0;for (int i=a;i;i-=lowbit(i))for (int j=b;j;j-=lowbit(j))ans+=t1[i][j]*((a+1)*(b+1))-t2[i][j]*(b+1)-t3[i][j]*(a+1)+t4[i][j];return ans;
}
void add1(int a,int b,int c,int d,int k)
//[a,b][c,d]为左上角和右下角的矩阵所有值加k
{add(a, b, k);add(c + 1, d + 1, k);add(a, d + 1, -k);add(c + 1, b, -k);
}
LL query_ans(int a,int b,int c,int d)
//求区间[a,b],[c,d]为左上角和右下角的和
{return sum(a-1,b-1)+sum(c,d)-sum(a-1,d)-sum(c,b-1);
}

ACM入门之【树状数组】相关推荐

  1. HDU ACM 4031 Attack (树状数组--单点查询+区间更新)

    http://acm.hdu.edu.cn/showproblem.php?pid=4031 用了树状数组的区间更新 单点查找(一般为单点更新 区间查找) 例如 区间(2,4)加1 则Updata(2 ...

  2. ACM入门之【树状数组习题】

    目录 130. 树状数组 1 :单点修改,区间查询 131. 树状数组 2 :区间修改,单点查询 132. 树状数组 3 :区间修改,区间查询 133. 二维树状数组 1:单点修改,区间查询 134. ...

  3. 树状数组入门——以洛谷3374为例

    树状数组入门 含义:顾名思义,用树状表示的数组 功能:是一个查询和修改复杂度都为log(n)的数据结构.主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值:经过简单修改可以在log( ...

  4. 2017 ACM/ICPC Asia Regional Shenyang Online Ping Ping Ping 树链剖分+树状数组

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=6203 题目大意:给出n+1个节点的树( 3<n<10^4),并给出m对点(m<=50 ...

  5. 掌握树状数组~彻底入门

    掌握树状数组~彻底入门 作者:霜雪千年 出处:http://www.cnblogs.com/acgoto/ 先贴一下树状数组的模板代码: int lowbit(int i) {return i &am ...

  6. HDU - 5877 Weak Pair 2016 ACM/ICPC 大连网络赛 J题 dfs+树状数组+离散化

    题目链接 You are given a rootedrooted tree of NN nodes, labeled from 1 to NN. To the iith node a non-neg ...

  7. 牛客网 暑期ACM多校训练营(第一场)J.Different Integers-区间两侧不同数字的个数-离线树状数组 or 可持久化线段树(主席树)...

    J.Different Integers 题意就是给你l,r,问你在区间两侧的[1,l]和[r,n]中,不同数的个数. 两种思路: 1.将数组长度扩大两倍,for(int i=n+1;i<=2* ...

  8. 【分解质因数】【树状数组】【快速幂】codeforces 2014 ACM-ICPC Vietnam National Second Round E. ACM...

    乘除都在150以内,分解质因数后发现只有35个,建立35个树状数组/线段树,做区间加.区间查询,最后快速幂起来. #include<cstdio> #include<cstring& ...

  9. 2017西安交大ACM小学期数据结构 [又是树状数组、异或]

    Problem F 发布时间: 2017年6月28日 10:31   最后更新: 2017年6月29日 21:35   时间限制: 2000ms   内存限制: 64M 描述 给定一个n×m的矩形, ...

最新文章

  1. 复杂SELECT语句执行过程
  2. 第一家科创板IPO的AI公司:年净利1.58亿,华为小米背后功臣,北大物理系校友创办...
  3. h5调用摄像头拍照可以自定义拍照页面吗_回归单摄时代?小米伸缩式摄像头技术曝光,网友:好家伙...
  4. Linux内存管理中的slab分配器
  5. 百度更新算法之后我想说
  6. 在maven本地仓库导入jar包
  7. checkcode.aspx 生成随即验证码
  8. 【转】BOM 和 DOM
  9. js 台阶有n级_乔欣这是“开眼角”了?只在眼妆中多加这一步,整个人变美了N倍...
  10. python输入多组数据_Python3算法类多组数据输入输出格式
  11. 六、hibernate之HQL
  12. React:工程化开发
  13. android无线充电技术,无线充电Qi通信协议分析,充电qi通信协议
  14. 严师出高徒VS名师出高徒
  15. win7默认网关不可用_Win7系统填写静态IP的方法是什么?
  16. aix 到 linux的网络,通过VIOS实现AIX系统的网络虚拟化
  17. ChatGpt常用指令大全
  18. 可以查看计算机主要自启动项的技术,电脑中怎么查看启动项
  19. SpringCloud——Eureka服务注册和发现
  20. CAS和自旋到底是一个概念吗?

热门文章

  1. ML之HierarchicalClustering:自定义HierarchicalClustering层次聚类算法
  2. Py之demjson:Python库之demjson的简介、安装、使用方法详细攻略
  3. pyhanlp 文本聚类
  4. Hyperopt中文文档:Cite引用
  5. ToStringBuilder学习(三):readResolve()方法与序列化
  6. 对于58同城自动登陆的补充【主要是代码】
  7. ST17H26上下拉电阻设置注意事项
  8. EOS 智能合约源代码解读 (6)合约之action
  9. Bitcoin 中的挖矿算法(3) 挖矿算法代码说明
  10. 基于SpringBoot和Vue的分布式爬虫系统(JavaWeb)