AcWing Problem - 一个简单的整数问题2
题目类型:树状数组
题意
有两种操作:
• 查询区间 [l, r] 内的和
• 对 [l, r] 内所有数加上 d
分析
使用两个树状数组来维护
代码
static int[] a;
static long[] C1;
static long[] C2;
public static void solve() throws IOException {
int n = nextInt();
int m = nextInt();
init(n, m);
for (int i = 1; i <= n; i++) a[i] = nextInt();
for (int i = 1; i <= n; i++) {
int dif = a[i] - a[i - 1];
add(i, dif, n, C1);
add(i, (long) i * dif, n, C2);
}
while (m-- > 0) {
char op = nextChar();
if (op == 'Q') {
int l = nextInt();
int r = nextInt();
pw.println(preSum(r, C1, C2) - preSum(l - 1, C1, C2));
} else {
int l = nextInt();
int r = nextInt();
int d = nextInt();
add(l, d, n, C1);
add(r + 1, -d, n, C1);
add(l, l * d, n, C2);
add(r + 1, (r + 1) * -d, n, C2);
}
}
}
public static void add(int x, long v, int n, long[] C) {
while (x <= n) {
C[x] += v;
x += lowbit(x);
}
}
public static long getSum(int x, long[] C) {
long re = 0;
while (x > 0) {
re += C[x];
x -= lowbit(x);
}
return re;
}
public static long preSum(int x, long[] C1, long[] C2) {
return getSum(x, C1) * (x + 1) - getSum(x, C2);
}
public static int lowbit(int x) { return x & (-x); }
public static void init(int n, int m) {
a = new int[n + 1];
C1 = new long[n + 1];
C2 = new long[n + 1];
}
/*******************************************************************************************/
/******************************************************************************************/
// Fast I/O