主席镇楼。
打了几天,终于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 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 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 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;
}
}
}
效率很低,代码很渣。有的是空间优化。