学习参考:
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