龙空技术网

Java树状数组「Binary Indexed Tree」应用

GeBee老王 69

前言:

如今各位老铁们对“树状数组单点查询”大致比较着重,各位老铁们都需要剖析一些“树状数组单点查询”的相关内容。那么小编同时在网摘上收集了一些有关“树状数组单点查询””的相关文章,希望大家能喜欢,你们快快来了解一下吧!

CSDN原创:

单点更新–求区间最大(小)值

import java.util.Arrays;public class BIT_MaxMin {    static final int maxN = 50;    static int N;    static int[] bitMax = new int[maxN];    static int[] bitMin = new int[maxN];    static int[] arr = new int[maxN];    public static void main(String[] args) throws Exception {        int[] in = new int[]{5, 6, 7, 7, 4, 2, 8, 3, 9, 9, 9, 10, 10, 11};        N = in.length;        for (int i = 1; i <= N; i++) {            arr[i] = in[i - 1];            update(i, arr[i]);        }        int[] ans = queryMaxMin(1, 7);        System.out.println("1~7区间最大值: " + ans[0]);//8        System.out.println("1~7区间最小值: " + ans[1]);//2    }    static int lowBit(int x) {        // x & x取反+1        return x & -x;    }    //最大最小可拆分成两个方法    static void update(int x, int val) {        arr[x] = val;        while (x <= maxN) {            bitMax[x] = arr[x];            bitMin[x] = arr[x];            for (int i = 1; i < lowBit(x); i *= 2) {                bitMax[x] = Math.max(bitMax[x], bitMax[x - i]);                bitMin[x] = Math.min(bitMin[x], bitMin[x - i]);            }            x += lowBit(x);        }    }    //最大最小可拆分成两个方法    static int[] queryMaxMin(int x, int y) {        int max = arr[y];        int min = arr[y];        while (y != x) {            for (y--; y - lowBit(y) >= x; y -= lowBit(y)) {                max = Math.max(max, bitMax[y]);                min = Math.min(min, bitMin[y]);            }            max = Math.max(max, arr[y]);            min = Math.min(min, arr[y]);        }        return new int[]{max, min};    }}
最长递增子序列的长度(LIS、LNDS)

LIS(Longest Increasing Subsequence):最长单调递增子序列长度

LNDS:最长不递减子序列长度

import java.util.Arrays;import java.util.Comparator;public class BIT_LIS_LNDS {    static final int maxN = 50;    static int N;    static int lis = 0, lnds = 0;    static Node[] lisArr = new Node[maxN];    static Node[] lndsArr = new Node[maxN];    static int[] bit = new int[maxN];    static Comparator<Node> lisCmp = new Comparator<Node>() {        @Override        public int compare(Node o1, Node o2) {            //lds 按值升序 索引降序            return o1.val == o2.val ? o2.idx - o1.idx : o1.val - o2.val;        }    };    static Comparator<Node> lndsCmp = new Comparator<Node>() {        @Override        public int compare(Node o1, Node o2) {            //lds 按值升序 索引升序            return o1.val == o2.val ? o1.idx - o2.idx : o1.val - o2.val;        }    };    public static void main(String[] args) {        int[] in = new int[]{5, 6, 7, 7, 4, 2, 8, 3, 9, 9, 9, 10, 10, 11};        //lis(7):5 6 7 8 9 10 11        //lnds(11):5 6 7 7 8 9 9 9 10 10 11        N = in.length;        for (int i = 0; i < N; i++) {            lisArr[i + 1] = new Node(i + 1, in[i]);            lndsArr[i + 1] = new Node(i + 1, in[i]);        }        Arrays.sort(lisArr, 1, N + 1, lisCmp);        for (int i = 1; i <= N; i++) {            int len = query(lisArr[i].idx) + 1;            update(lisArr[i].idx, len);            lis = Math.max(lis, len);        }        System.out.println("lis: " + lis);        Arrays.fill(bit, 0);        Arrays.sort(lndsArr, 1, N + 1, lndsCmp);        for (int i = 1; i <= N; i++) {            int len = query(lndsArr[i].idx) + 1;            update(lndsArr[i].idx, len);            lnds = Math.max(lnds, len);        }        System.out.println("lnds: " + lnds);    }    static int lowBit(int x) {        // x & x取反+1        return x & -x;    }    static void update(int x, int val) {        while (x < maxN) {            bit[x] = Math.max(bit[x], val);            x += lowBit(x);        }    }    static int query(int x) {        int max = 0;        while (x > 0) {            max = Math.max(bit[x], max);            x -= lowBit(x);        }        return max;    }    static class Node {        int idx;        int val;        Node(int idx, int val) {            this.idx = idx;            this.val = val;        }    }}
最长递减子序列的长度(LDS、LNIS)

LDS(Longest Decreasing Subsequence):最长单调递减子序列长度

LNIS:最长不递增子序列长度

import java.util.Arrays;import java.util.Comparator;public class BIT_LDS_LNIS {    static final int maxN = 50;    static int N;    static int lds = 0, lnis = 0;    static Node[] ldsArr = new Node[maxN];    static Node[] lnisArr = new Node[maxN];    static int[] bit = new int[maxN];    static Comparator<Node> ldsCmp = new Comparator<Node>() {        @Override        public int compare(Node o1, Node o2) {            //lds 按值升序 索引升序            return o1.val == o2.val ? o1.idx - o2.idx : o1.val - o2.val;        }    };    static Comparator<Node> lnisCmp = new Comparator<Node>() {        @Override        public int compare(Node o1, Node o2) {            //lnis 按值升序 索引降序            return o1.val == o2.val ? o2.idx - o1.idx : o1.val - o2.val;        }    };    public static void main(String[] args) {        int[] in = new int[]{11, 10, 10, 9, 9, 9, 3, 8, 2, 4, 7, 7, 6, 5};        //lds(7):11 10 9 8 7 6 5        //lnis(11):11 10 10 9 9 9 8 7 7 6 5        N = in.length;        for (int i = 0; i < N; i++) {            ldsArr[i + 1] = new Node(i + 1, in[i]);            lnisArr[i + 1] = new Node(i + 1, in[i]);        }        Arrays.sort(ldsArr, 1, N + 1, ldsCmp);        for (int i = N; i >= 1; i--) {            int len = query(ldsArr[i].idx) + 1;            update(ldsArr[i].idx, len);            lds = Math.max(lds, len);        }        System.out.println("lds: " + lds);        Arrays.fill(bit, 0);        Arrays.sort(lnisArr, 1, N + 1, lnisCmp);        for (int i = N; i >= 1; i--) {            int len = query(lnisArr[i].idx) + 1;            update(lnisArr[i].idx, len);            lnis = Math.max(lnis, len);        }        System.out.println("lnis: " + lnis);    }    static int lowBit(int x) {        // x & x取反+1        return x & -x;    }    static void update(int x, int val) {        while (x < maxN) {            bit[x] = Math.max(bit[x], val);            x += lowBit(x);        }    }    static int query(int x) {        int max = 0;        while (x > 0) {            max = Math.max(bit[x], max);            x -= lowBit(x);        }        return max;    }    static class Node {        int idx;        int val;        Node(int idx, int val) {            this.idx = idx;            this.val = val;        }    }}
单点更新–求区间和
public class BIT_Sum {    static final int maxN = 50;    static int N;    static int[] bit = new int[maxN];    public static void main(String[] args) throws Exception {        int[] in = new int[]{5, 6, 7, 7, 4, 2, 8, 3, 9, 9, 9, 10, 10, 11};        N = in.length;        for (int i = 0; i < N; i++) {            update(i + 1, in[i]);//初始化        }        //第x~y项的区间和 query(y) - query(x-1)        //第x项的值改为y update(x, y)        System.out.println(query(5) - query(2 - 1));//2~5项的区间和 6+7+7+4=24        update(3, 10 - 7);//第三项由7改为10        System.out.println(query(5) - query(2 - 1));//2~5项的区间和 6+10+7+4=27    }    static int lowBit(int x) {        return x & (-x);    }    static void update(int x, int val) {        while (x < maxN) {            bit[x] += val;            x += lowBit(x);        }    }    static int query(int x) {        int sum = 0;        while (x > 0) {            sum += bit[x];            x -= lowBit(x);        }        return sum;    }}
区间更新–求区间和–单点查询

区间更新,暴力方法:遍历区间,对区间中每个值更新,再求和。

优化方法:使用差分数组

代码待更新

这个博客写得很好

[]

标签: #树状数组单点查询