首页 > 其他分享 >树状数组学习笔记与总结

树状数组学习笔记与总结

时间:2023-07-12 13:57:17浏览次数:53  
标签:return 树状 int 笔记 getsum 数组 区间

树状数组学习笔记与总结

目录

树状数组

OI Wiki

OI Wiki - 树状数组

信息学奥赛一本通

img
img
img

例题

单点修改,区间查询

LibreOJ 树状数组 1:单点修改,区间查询

我的代码

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 10;
int n, q;
int w[N], tr[N];
int lowbit(int x) {
    return x & -x;
}
void add(int x, int k) {
    while (x <= n) {
        tr[x] += k;
        x += lowbit(x);
    }
}
int getsum(int x) {
    int sum = 0;

    while (x > 0) {
        sum += tr[x];
        x -= lowbit(x);
    }

    return sum;
}
int getsum(int l, int r) {
    return getsum(r) - getsum(l - 1);
}
void init() {
    for (int i = 1; i <= n; i ++) {
        tr[i] += w[i];
        int j = i + lowbit(i);

        if (j <= n)
            tr[j] += tr[i];
    }
}
signed main() {
    scanf("%lld%lld", &n, &q);

    for (int i = 1; i <= n; i ++)
        scanf("%lld", w + i);

    init();
    int op, x, y;

    while (q --) {
        scanf("%lld%lld%lld", &op, &x, &y);

        if (op == 1)
            add(x, y);
        else
            printf("%lld\n", getsum(x, y));
    }
}

区间修改,单点查询

LibreOJ 树状数组 2:区间修改,单点查询

我的代码

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 10;
int n, q;
int a[N], d[N], tr[N];
int lowbit(int x) {
    return x & -x;
}
void add(int x, int k) {
    while (x <= n) {
        tr[x] += k;
        x += lowbit(x);
    }
}
void add(int l, int r, int k) {
    add(l, k), add(r + 1, -k);
}
int getsum(int x) {
    int sum = 0;

    while (x > 0) {
        sum += tr[x];
        x -= lowbit(x);
    }

    return sum;
}
void init() {
    for (int i = 1; i <= n; i ++) {
        tr[i] += d[i];
        int j = i + lowbit(i);

        if (j <= n)
            tr[j] += tr[i];
    }
}
signed main() {
    scanf("%lld%lld", &n, &q);

    for (int i = 1; i <= n; i ++)
        scanf("%lld", a + i), d[i] = a[i] - a[i - 1];

    init();
    int op, l, r, x;

    while (q --) {
        scanf("%lld%lld", &op, &l);

        if (op == 1)
            scanf("%lld%lld", &r, &x), add(l, r, x);
        else
            printf("%lld\n", getsum(l));
    }
}

区间修改,区间查询

LibreOJ 树状数组 3:区间修改,区间查询

我的代码

点击查看代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 10;
int n, q;
int a[N], d[N], t1[N], t2[N];
int lowbit(int x) {
    return x & -x;
}
void add(int x, int k) {
    int v = x * k;

    while (x <= n) {
        t1[x] += k, t2[x] += v;
        x += lowbit(x);
    }
}
void add(int l, int r, int k) {
    add(l, k), add(r + 1, -k);
}
int getsum(int *tr, int x) {
    int sum = 0;

    while (x > 0) {
        sum += tr[x];
        x -= lowbit(x);
    }

    return sum;
}
int getsum(int x) {
    return getsum(t1, x) * (x + 1) - getsum(t2, x);
}
int getsum(int l, int r) {
    return getsum(r) - getsum(l - 1);
}
void init() {
    for (int i = 1; i <= n; i ++) {
        t1[i] += d[i], t2[i] += d[i] * i;
        int j = i + lowbit(i);

        if (j <= n)
            t1[j] += t1[i], t2[j] += t2[i];
    }
}
signed main() {
    scanf("%lld%lld", &n, &q);

    for (int i = 1; i <= n; i ++)
        scanf("%lld", a + i), d[i] = a[i] - a[i - 1];

    init();
    int op, l, r, x;

    while (q --) {
        scanf("%lld%lld%lld", &op, &l, &r);

        if (op == 1)
            scanf("%lld", &x), add(l, r, x);
        else
            printf("%lld\n", getsum(l, r));
    }
}

标签:return,树状,int,笔记,getsum,数组,区间
From: https://www.cnblogs.com/MingruiYang/p/17547283.html

相关文章

  • python学习笔记:继承与超类
    与java类似,继承的出现是为了提高代码的重复利用率,避免多次输入同样的代码。而超类就是java中的父类。1.继承要指定超类,可在定义类时,在class语句中的类名后加上超类名基类就是超类,派生类就是子类格式classDog:# passclassBobo(Dog):#Dog类的子类 pass子类会......
  • Go--统计数组中重复的元素及重复次数
    代码:packagemainimport("fmt")funcmain(){//创建有重复数值的数组a1:=[]int{1,2,3,1,4,5,2}a2:=[]string{"t1","t2","t1","t3","t5","t3"}//创建maps1:=......
  • LeetCode -- 918. 环形子数组的最大和
     遇到环形问题一般有两种考虑方法:1.破环成链2.分为数组中间部分和数组两边部分分别考虑本题采用第二种考虑方法,将原数组分为中间部分和两边部分分别考虑。中间部分即为子数组最大和,两边部分计总和减去中间部分最小和。classSolution{public:intma......
  • JS-Forward 学习笔记
    什么是JS-Forward?不了解的同学,可以先看看JS-Forward的Github仓库介绍,https://github.com/G-Security-Team/JS-ForwardJS-Forward是一款可以配合类似BurpSuite等抓包软件的脚本,脚本的功能是可以将js里面的参数通过Http请求将参数发送出来,在外部进行修改,最后将修改后的返回值再......
  • JavaScript 将对象数组按字母顺序排序
    原文链接:JavaScript将对象数组按字母顺序排序这里给出三种解决方案:1.if条件语句+sort()2.localeCompare()+sort()3.Collator()+sort()sort用法语法array.sort(compareFunction)参数值参数描述compareFunction可选。定义替代排序顺序的函数。该函数......
  • 组合数学 笔记
    组合数学笔寄加法原理完成一个事情有\(n\)类做法,第\(i\)类做法又分为\(a_i\)种。所以这件事情有\(S=\sum_{i=1}^{n}a_i\)的不同的完成方法。乘法原理草字头有\(3\)种写法,回字有\(4\)种写法,所以茴香豆的茴有\(S=3\times4\)种写法。同样,一件事情有\(n\)个步......
  • 【学习笔记】空空的浅谈DP
    特邀讲师:墨染空洛谷用户@Remakedalao博客中的学习笔记:https://www.cnblogs.com/dmoransky/p/14063918.htmlDP1决策单调性1.2由已知量转移:分治算法洛谷P3515:[POI2011]LightningConductor1.3由之前状态转移:单调栈上二分洛谷P1912:[NOI2009]诗人小G\(f......
  • Jquery遍历筛选数组的几种方法和遍历解析json对象,Map()方法详解以及数组中查询某值是
    1.jquerygrep()筛选遍历数组(可以得到反转的数组)//1.jquerygrep()筛选遍历数组(可以得到反转的数组)vararray=[1,5,9,3,12,4,48,98,4,75,2,10,11];varfilterArray=$.grep(array,(currentValue)=>{returncurrentValue>10;});console.log(`${filt......
  • markdown笔记
    #markdown##二级标题###三级标题####四级标题#####五级标题######六级标题#加文字加空格,一个#是一级标题,两个#是二级标题,以此类推,最多只有六级标题。菜单栏里“视图”-“大纲”,已有的标题会在大纲中显示,可以选择是否折叠显示。 ##字体**粗体***斜体****粗体加......
  • 树状数组
    概念https://zhuanlan.zhihu.com/p/92920381树状数组(BinaryIndexedTree,又FenwickTree)其实并不是一棵树,只是对数组各元素进行逻辑上的划分。根据维基百科,树状数组是一种用于高效计算数列前缀和的数据结构,它可以以O(logn)的时间得到任意前缀和(两个前缀和相减即可得到区间和),并......