树状数组review学习

学习参考:

https://blog.csdn.net/flushhip/article/details/79165701

https://blog.csdn.net/moep0/article/details/52770728

树状数组在寒假集训的时候其实有讲过,但是当时只是有了板子,没有很深地去学习理解,现在回来想去理解一下这个很好用的数据结构。

树状数组的作用

树状数组是对于一个用来处理动态更新、动态统计区间问题的一种良好的数据结构,查询和修改复杂度都为O(logn)的数据结构。

树状数组主要对于单点修改,区间查询进行操作。

lowbit()

比如求出2^p(其中p: x 的二进制表示数中, 右向左数第一个1的位置),如6的二进制表示为110,向左数第零个为0,第一个为1,则p=1,故Lowbit(6) = 2^1 = 2。

lowbit这个的主要作用是求一个数二进制中最低一位的1,常用的lowbit函数很巧地运用了负整数补码的特性。代码如下

int lowbit(int x)
{
    return x&(-x);
}

几个操作:把第i个数加上x,修改第i个数的值,删除第i个数,统计第i到第j个数的和

树状数组的原理是增加一个辅助序列C数组,令C[i]=a[i-2k+1]+a[i-2k+2]+…+a[i],其中k为i在二进制形式下末尾0的个数。

 1 #include <bits/stdc++.h>
 2 #define fi first
 3 #define se second
 4 #define pb push_back
 5 #define fio ios::sync_with_stdio(false);cin.tie(0);
 6 #define pii pair<int,int>
 7 #define vi vector<int>
 8 #define vc vector<char>
 9 #define mii map<int,int>
10 #define si(a) scanf("%d",&a)
11 #define ss(a) scanf("%s",&a)
12 #define sl(a) scanf("%I64d",&a);
13 #define slf(a) scanf("%lf",&a);
14 #define CLEAR(a,b) memset(a,b,sizeof(a))
15 #define pi acos(-1)
16
17 typedef double db;
18 typedef long long ll;
19 typedef unsigned long long ull;
20
21 const int INF=0x3f3f3f3f;
22 const int N=2e5+5;
23 using namespace std;
24 int s[N];
25 int n;
26 int lowbit(int x)
27 {
28     return x&(-x);
29 }
30
31 void add(int i,int j)
32 {
33     while (i<=n)
34     {
35         s[i]+=j;
36         i+=lowbit(i);
37     }
38 }
39
40
41 int Query(int k)
42 {
43     int re=0;
44     while (k>0)
45     {
46         re+=s[k];
47         k-=lowbit(k);
48     }
49     return re;
50 }
51
52
53 void sub(int i,int j)
54 {
55     while (i<=n)
56     {
57         s[i]-=j;
58         i+=lowbit(i);
59     }
60 }
61
62
63 int main()
64 {
65
66 }

原文地址:https://www.cnblogs.com/TheSilverMoon/p/9459684.html

时间: 2024-10-29 00:26:05

树状数组review学习的相关文章

树状数组 浅显学习

学习来源 首先要明确树状数组的本质就是带修改的前缀和,它每次用 lowbit 来很巧妙的寻找所属前缀的位置 在这些位置+k 然后还是用 lowbit 来查询这段和应该属于的树状数组的位置. 最简单的就是单点更新和区间查询,或者区间更新 int c[maxn];//树状数组 int n;//树状数组的大小 int lowbit(int x) { return x & (-x); } void update(int i,int k) { while(i>0) { c[i] += k; i -=

hdu 5249区间第k大(学习了下树状数组的搞法)

KPI Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 205    Accepted Submission(s): 70 Problem Description 你工作以后, KPI 就是你的全部了. 我开发了一个服务,取得了很大的知名度.数十亿的请求被推到一个大管道后同时服务从管头拉取请求.让我们来定义每个请求都有一个重要值.我的K

【学习整理】树状数组 区间修改+查询

前言:对于区间修改和区间查询这样的简单问题,打一大堆线段树确实是不划算,所以学习了区间修改+区间修查询的树状数组. 我们定义 为原数列, ,显然  . 若想要将区间 的数全部 则只需要将 , 即可. 所以,我们维护一个数组 在将区间 的数全部 则还需同时将 , . 结论: 例题:CODEVS1082 线段树练习3 http://codevs.cn/problem/1082/ #include<iostream> #include<cstdio> #include<cstdli

学习笔记——二维树状数组

不知道为什么,就是想把这个坑给填了... 二维树状数组,本质上还是树状数组,只是在一维的基础上变成了二维... 单点修改  1到i,j查询和一维基本一样,直接上代码 #include<iostream> #include<cstdlib> #include<cstdio> #include<algorithm> #define N 3010 using namespace std; int a[N][N],n; inline int lowbit(int x

树状数组学习资料1

1 一维树状数组 1 什么是树状数组 树状数组是一个查询和修改复杂度都为log(n)的数据结构,假设数组A[1..n],那么查询A[1]+...+A[n]的时,间是log级别的,而且是一个在线的数据结构. 2 树状数组作用 我们经常会遇到动态连续和查询问题,给定n个元素A[1~N],让我们求sum[L,R] = A[L]+...+A[R],或者更改A[i]的值. 假设数据很小的时候,那么我们利用暴力就可以搞定,这个时候更改A[i]的复杂度为O(1),但是求和的复杂度为O(n),如果有m次求和就是

【算法学习笔记】40.树状数组 动态规划 SJTU OJ 1289 扑克牌分组

Description cxt的扑克牌越来越先进了,这回牌面的点数还可以是负数, 这回cxt准备给扑克牌分组,他打算将所有的牌分成若干个堆,每堆的牌面总和和都要大于零.由于扑克牌是按顺序排列的,所以一堆牌在原牌堆里面必须是连续的.请帮助cxt计算一下,存在多少种不同的分牌的方案.由于答案可能很大,只要输出答案除以1,000,000,009的余数即可. Input Format 第一行:单个整数:N,1 ≤ N ≤ 10^6 第二行到N + 1行:在第i + 1行有一个整数:Ai, 表示第i张牌牌

ACM学习历程—51NOD 1685 第K大区间2(二分 &amp;&amp; 树状数组 &amp;&amp; 中位数)

http://www.51nod.com/contest/problem.html#!problemId=1685 这是这次BSG白山极客挑战赛的E题. 这题可以二分答案t. 关键在于,对于一个t,如何判断它是否能成为第k大. 将序列中大于t的置为1,小于t的置为-1,等于t的置为0.那么区间中位数大于t的和就大于0,小于t的就小于0.于是就是判断区间和大于0的个数是否小于等于k. 维护前缀和sum(i),然后统计之前sum(j)小于sum(i)的有多少个,就是以i为右值的区间和大于0的个数.于

ACM学习历程—HDU4417 Super Mario(树状数组 &amp;&amp; 离线)

Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping ability reminded in our memory. Now the poor princess is in trouble again and Mario needs to save his lover. We regard the road to the boss’s castle as a line (

ACM学习历程—SNNUOJ 1239 Counting Star Time(树状数组 &amp;&amp; 动态规划 &amp;&amp; 数论)

http://219.244.176.199/JudgeOnline/problem.php?id=1239 这是这次陕西省赛的G题,题目大意是一个n*n的点阵,点坐标从(1, 1)到(n, n),每个点都有权值,然后从(x, y)引x轴的垂线,然后构成一个三角形,三个顶点分别是(0, 0),(x, 0)和(x, y).求三角形内点的权值和,包括边界,n的范围是1000,m的范围是100000,说起来也比较坑..学弟n*m的复杂度竟然水过去了,目测比赛数据比较水..不过我挂到我们OJ上给了一组随