📑前言
本文主要是【树状数组】——树状数组简单使用的文章,如果有什么需要改进的地方还请大佬指出⛺️
🎬作者简介:大家好,我是听风与他🥇
☁️博客首页:CSDN主页听风与他
🌄每日一句:狠狠沉淀,顶峰相见
目录
- 📑前言
- 树状数组模板示例
- 模板代码:
- 1208.小球与盒子
- 📑文章末尾
树状数组模板示例
- 以1–8为例,构建树状数组
我们知道lowbit的性质是,奇数等于1,2的次方等于本身,偶数为第一次出现的0,如4:100,lowbit(4)=4
A数组和C数组之间的关系为
C1=A1
C2=A1+A2
C3=A3
C4=A1+A2+A3+A4
C5=A5
C6=A5+A6
C7=A7
C8=A1+A2+A3+A4+A5+A6+A7+A8
模板代码:
package 难点攻克;import java.util.Arrays;public class TreeArray {static int[] A;//原始的数据static int[] C;//树状数组static int n;//数组的元素个数public TreeArray(int[] A) {this.A=new int[A.length];n = A.length;C = new int[n+1];//c[0]不用for(int i=1;i<=A.length;i++) {update(i, A[i-1]);}}public static int lowbit(int x) {return x&(-x);}public static void update(int i,int val) { //原来的值A[i-1],现在的值是valSystem.out.println("val:"+val+" i:"+A[i-1]);int data = val-A[i-1];//新旧值之间的差距
// System.out.println("data:"+data);A[i-1]=val;//将A的第i个元素(生活中,计算机里面i-1)修改新的值valfor(int pos=i;pos<=n;pos=pos+lowbit(pos)) {C[pos] += data;}}public static int sumRange(int start,int end) {if(start<1 || start>n || end<1 ||end>n) {return -1;}else {return sum02k(end)-sum02k(start-1);}//sum02k(end)=A1+A2+...+Astart-1 + Astart +...+Aend//sum02k(end)=A1+A2+...+Astart-1}public static int sum02k(int pos) {//c[pos]+c[pos-lowbit[pos]]+...int sum = 0;for(int i=pos;i>=1;i=i-lowbit(i)) {sum=sum+C[i];}//sum(A(1)->A(7)) =>c[7]+C[7-lowbit[7])+c[6-lowbit(6))=c7+c6+c4return sum;}public static void main(String[] args) {// TODO Auto-generated method stubint[] a = {1,2,3,4,5,6,7,8};TreeArray t = new TreeArray(a);System.out.println(Arrays.toString(t.C));t.update(3, 99);System.out.println(Arrays.toString(t.A));System.out.println(Arrays.toString(t.C));System.out.println("前2个的和:"+t.sum02k(2));System.out.println("前6个的和:"+t.sum02k(6));System.out.println("2-6个的和:"+t.sumRange(2, 6));}}
1208.小球与盒子
package 难点攻克;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Arrays;public class Main {static long[] A;static long[] C;static int n;public Main(long[] A) {this.A = new long[A.length];n = A.length;C = new long[n+1];for(int i=1;i<=n;i++) {update(i, A[i-1]);}}public static int lowbit(int x) {return x&(-x);}public static void update(int i,long val) {long data = val;A[i-1]=val;for(int pos=i;pos<=n;pos=pos+lowbit(pos)) {C[pos]+=data;}}public static long sum02k(int i) {long ans = 0;for(int pos=i;pos>=1;pos=pos-lowbit(pos)) {ans+=C[pos];}return ans;}public static long Sum(int start,int end) {return sum02k(end)-sum02k(start-1);}public static void main(String[] args) throws IOException {// TODO Auto-generated method stubStreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));sc.nextToken();int n = (int)sc.nval;long nums[] = new long[n];Main t = new Main(nums);sc.nextToken();int m =(int)sc.nval;while(m-->0) {sc.nextToken();int op=(int)sc.nval;sc.nextToken();int x=(int)sc.nval;sc.nextToken();int y=(int)sc.nval;if(op==1) {update(x, y);}else {System.out.println(Sum(x, y));}}}}