树状数组

小鱼儿 2023-05-21 08:59 64阅读 0赞

区间查询和单点修改

单点修改

  1. void update(int x,int v)
  2. {
  3. for(int i=x;i<=n;i+=lowbit(i)){
  4. a[i]+=v;
  5. }
  6. }

区间查询
L~R的sum即 : getsum® - getsum(L-1);

  1. int getsum(int x)
  2. {
  3. int sum=0;
  4. for(int i=x;i>0;i-=lowbit(i)){
  5. sum+=a[i];
  6. }
  7. return sum;
  8. }

求lowbit

  1. int lowbit(int x)
  2. {
  3. return x&(-x);
  4. }

区间修改和单点查询

(利用差分数组)
如题,已知一个数列,你需要进行下面两种操作:

将某区间每一个数数加上 xx;

求出某一个数的值。

输入格式
第一行包含两个整数 NN、MM,分别表示该数列数字的个数和操作的总个数。

第二行包含 NN 个用空格分隔的整数,其中第 ii 个数字表示数列第 i i 项的初始值。

接下来 MM 行每行包含 22 或 44个整数,表示一个操作,具体如下:

操作 11: 格式:1 x y k 含义:将区间 [x,y][x,y] 内每个数加上 kk;

操作 22: 格式:2 x 含义:输出第 xx 个数的值。

输出格式
输出包含若干行整数,即为所有操作 22 的结果。

输入输出样例
输入 #1 复制
5 5
1 5 4 2 3
1 2 4 2
2 3
1 1 5 -1
1 3 5 7
2 4
输出 #1 复制
6
10

  1. #include<cstdio>
  2. #include<iostream>
  3. using namespace std;
  4. typedef long long ll;
  5. int n,m;
  6. ll a[500010];
  7. ll b[500010];
  8. int lowbit(int x)
  9. {
  10. return x&(-x);
  11. }
  12. void update(int x,int k)
  13. {
  14. for(int i=x;i<=n;i+=lowbit(i))
  15. {
  16. b[i]+=k;
  17. }
  18. }
  19. ll getx(int x)
  20. {
  21. ll ans=0;
  22. for(int i=x;i>0;i-=lowbit(i))
  23. {
  24. ans+=b[i];
  25. }
  26. return a[x]+ans;
  27. }
  28. int main()
  29. {
  30. scanf("%lld%lld",&n,&m);
  31. for(int i=1;i<=n;i++)
  32. {
  33. scanf("%lld",&a[i]);
  34. }
  35. int x,y,k,t;
  36. while(m--)
  37. {
  38. scanf("%d",&t);
  39. if(t==1)
  40. {
  41. scanf("%d%d%d",&x,&y,&k);
  42. update(x,k);update(y+1,-k);
  43. }
  44. else
  45. {
  46. scanf("%d",&x);
  47. printf("%lld\n",getx(x));
  48. }
  49. }
  50. return 0;
  51. }

发表评论

表情:
评论列表 (有 0 条评论,64人围观)

还没有评论,来说两句吧...

相关阅读

    相关 树状数组

    目录: 1. 概念 2. 应用 3. 充分性 4. 建立树状数组 5. 典题分析   一.概念 数组来模拟树形结构。那么、为什么不直接建树?没必要,因为树

    相关 树状数组

    1、概述 树状数组(binary indexed tree),是一种设计新颖的数组结构,它能够高效地获取数组中连续n个数的和。概括说,树状数组通常用于解决以下问题:数组\{a

    相关 树状数组

    树状数组 树状数组:用线性数据结构的方法解决动态统计子树权和的问题。 类似于线段树,将区间分成小段,方便计算权和。 举个栗子,将a数组构造成树状数组c。 如果a

    相关 树状数组初探

    前言 在前一篇文章:[线段树初探][Link 1] 中我们看了一下线段树的基本思想并且知道了线段树擅长于解决区间问题。其实对于某些区间问题,我们不仅可以用线段树解决,还可

    相关 树状数组实现

    树状数组能够完成如下操作: 给一个序列a0-an 计算前i项和 对某个值加x 时间o(logn) 注意:有人觉得前缀和就行了,但是你还要维护啊,改变某个值,一个一个改