学会了主席树!!!!!

这里写图片描述

主席镇楼。

打了几天,终于ac了hdu 4348(to the moon),主席树裸题。

完全不想写题解。

public class Main {
    static int[] input = new int[100005];

    public static void main(String[] args) {
        // Scanner reader = new Scanner(System.in);
        InputReader reader = new InputReader();
        while (reader.hasNext()) {
            int n = reader.nextInt();
            int m = reader.nextInt();
            for (int i = 1; i <= n; i++) {
                input[i] = reader.nextInt();
            }
            int last = 0;
            // new Node(null ,null);
            ArrayList<Node> tree = new ArrayList<>();
            tree.add(build(1, n));
            while (m-- > 0) {
                char com = reader.next().charAt(0);
                int L = reader.nextInt();
                int R = 0;
                switch (com) {
                case 'Q':
                    // System.out.println(last);
                    R = reader.nextInt();
                    System.out.println(sum(L, R, tree.get(last), 1, n));
                    break;
                case 'H':
                    R = reader.nextInt();
                    int t = reader.nextInt();
                    System.out.println(sum(L, R, tree.get(t), 1, n));
                    break;
                case 'C':
                    R = reader.nextInt();
                    int val = reader.nextInt();
                    tree.add(update(tree.get(last++), L, R, 1, n, val));
                    // tree.add(set(L, val, tree.get(last++), 1, n));
                    break;
                default:
                    last = L;
                    ArrayList<Node> newTree = new ArrayList<>();
                    for (int i = 0; i <= L; i++) {
                        newTree.add(tree.get(i));
                    }
                    tree = newTree;
                    break;
                }
            }
            // bfs(tree.get(last));
            // System.out.println();
        }
    }

    public static void bfs(Node root) {
        Queue<Node> wait = new LinkedList<>();
        wait.add(root);
        while (!wait.isEmpty()) {
            Node get = wait.poll();
            if (get.left != null) {
                wait.add(get.left);
            }
            if (get.right != null) {
                wait.add(get.right);
            }
            System.out.print(get.sum + " ");
        }
        System.out.println();
    }

    public static Node build(int left, int right) {
        if (left == right)
            return new Node(input[left]);
        return new Node(build(left, (left + right) / 2), build((left + right) / 2 + 1, right));
    }

    public static long sum(int a, int b, Node root, int left, int right) {
        if (a > right || b < left)
            return 0;
        // root.lazy * (right - left + 1)
        // long extra = 0;
        if (a <= left && right <= b)
            return root.sum;
        pushDown(root, left, right);
        return sum(a, b, root.left, left, (left + right) / 2) + sum(a, b, root.right, (left + right) / 2 + 1, right);
    }

    public static Node set(int pos, int value, Node root, int left, int right) {
        if (left == right)
            return new Node(value);
        int mid = (left + right) / 2;
        if (pos <= mid)
            return new Node(set(pos, value, root.left, left, mid), root.right);
        else
            return new Node(root.left, set(pos, value, root.right, mid + 1, right));
    }

    public static Node update(Node root, int L, int R, int l, int r, long val) {
        if (l >= L && r <= R) {
            // new Node(root.sum + val * (r - l + 1));
            // take.sum += val * (r - l + 1);
            Node take = root.colne(val * (r - l + 1));
            take.lazy += val;
            // System.out.println(l + " " + r);
            return take;
        }
        int mid = (l + r) / 2;
        pushDown(root, l, r);
        if (R <= mid) {
            return new Node(update(root.left, L, R, l, mid, val), root.right);
        }
        if (L > mid) {
            return new Node(root.left, update(root.right, L, R, mid + 1, r, val));
        }
        return new Node(update(root.left, L, R, l, mid, val), update(root.right, L, R, mid + 1, r, val));
    }

    public static void pushDown(Node root, int left, int right) {
        if (root.lazy == 0) {
            return;
        }
        // System.out.println(left + " " + right);
        // System.out.println(root.lazy);
        int mid = (left + right) / 2;
        root.left = root.left.colne(root.lazy * (mid - left + 1));
        root.right = root.right.colne(root.lazy * (right - mid));
        root.left.lazy += root.lazy;
        root.right.lazy += root.lazy;
        root.lazy = 0;
    }

    static class Node {
        Node left, right;
        long sum;
        long lazy;

        Node(long value) {
            this.sum = value;
        }

        Node(Node left, Node right) {
            this.left = left;
            this.right = right;
            if (left != null)
                sum += left.sum;
            if (right != null)
                sum += right.sum;
        }

        public Node colne(long add) {
            Node copy = new Node(this.sum + add);
            copy.left = this.left;
            copy.right = this.right;
            copy.lazy = this.lazy;
            return copy;
        }
    }
}

效率很低,代码很渣。有的是空间优化。

猜你喜欢

转载自blog.csdn.net/cymbals/article/details/80397267