Algorithm - 数据结构 - 树状数组(BinaryIndexedTree)
题型: 大量数据, 快速修改某一元素并且能求其中某一段和
原理: 修改某一元素时, 利用快速二分修改与其相关的数据, 也利用二分来进行快速求和
如图, 按照二分来进行求和 C8 = C4 + (C6 + (C7 + C8))
也按照二分来进行修改数据 C1 -> C2 -> C4 -> C8
实现:
struct BinaryIndexedTree{ //数组大小 int n; //源数组 int arr[] // 初始化 void Init(int noa){ n = noa; for(int i = 0; i < n; i ++){ arr[i] = 0; } } // 快速求下项 int lowbit(int k){ return k & -k; } // 插入 // index: 位置 // val: 值 void insert(int index, int val){ for(int i = index; i <= n; i += lowbit(index)){ arr[index] += val; } /* while(index <= n){ arr[index] += val; index = index + lowbit(index); } */ } // 求和 // index: 从 0 到 index 区间 int getSum(int index){ int sum = 0; for(int i = index; i > 0; i -= lowbit(index)){ sum += arr[index]; } /* while(index > 0){ sum += arr[index]; index = index - lowbit(index); } */ return sum; } }
变种题型: 二位树状数组
实现:
struct BinaryIndexedTree{ //矩阵大小(按照正方形来计算) int n; //源矩阵 int arr[][]; // 初始化 void Init(int noa){ n = noa; for(int i = 0; i < n; i ++){ for(int j = 0; j < n; j ++_){ arr[i][j] = 0; } } } // 快速求下项 int lowbit(int k){ return k & -k; } // 插入 // x, y: 坐标位置 // val: 值 void insert(int x, int y, int val){ for(int i = x; i <= n; i += lowbit(i)){ for(int j = y; j <= n; j += lowbit(j)){ arr[i][j] += val; } } } // 求和 // x, y: 从 (0, 0) 到 (x, y) 区间 int getSum(int x, int y){ int sum = 0; for(int i = x; i > 0; i -= lowbit(i)){ for(int j = y; j > 0; j -= lowbit(j)){ sum += arr[i][j]; } } return sum; } }
变种题型: 二位逆置树状数组, 与正常树状数组相反, 改变的是一段区间, 求一个点的值
实现:
struct BinaryIndexedTree{ //矩阵大小(按照正方形来计算) int n; //源矩阵 int arr[][]; // 初始化 void Init(int noa){ n = noa; for(int i = 0; i < n; i ++){ for(int j = 0; j < n; j ++_){ arr[i][j] = 0; } } } // 快速求下项 int lowbit(int k){ return k & -k; } // 插入 // x, y: 坐标位置 // val: 值 void insert(int x, int y, int val){ // 要需要一整片区间的值 // 从 (x,y) 到 (0,0) 进行迭代 for(int i = x; i > 0; i -= lowbit(i)){ for(int j = y; j > 0; j -= lowbit(j)){ arr[i][j] += val; } } } // 求和 // x, y: 从 (0, 0) 到 (x, y) 区间 int getSum(int x, int y){ int sum = 0; // 要求一点的和 // 从 (x, y) 到 (n, n) 进行迭代 for(int i = x; i <= n; i += lowbit(i)){ for(int j = y; j <= n; j += lowbit(j)){ sum += arr[i][j]; } } return sum; } }