Description
给出了一个序列,你需要处理如下两种询问。
"C a b c"表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000)。
"Q a b" 询问[a, b]区间中所有值的和。
Input
第一行包含两个整数N, Q。1 ≤ N,Q ≤ 100000.
第二行包含n个整数,表示初始的序列A (-1000000000 ≤ Ai ≤ 1000000000)。
接下来Q行询问,格式如题目描述。
Output
对于每一个Q开头的询问,你需要输出相应的答案,每个答案一行。
Sample Input
10 5 1 2 3 4 5 6 7 8 9 10 Q 4 4 Q 1 10 Q 2 4 C 3 6 3 Q 2 4
Sample Output
4 55 9 15
此题和上两题相似,但是区间更新和区间查询,我用了树状数组,zkw线段树还不会区间更新;直接上代码:
1 import java.io.BufferedInputStream; 2 import java.util.Scanner; 3 4 public class Main { 5 static int n; 6 static long[] arr = new long[1000001]; 7 static long sun;static long c1[] = new long[100005]; 8 static long c2[] = new long[100005];static String order; 9 10 public static void main(String[] args) throws Exception { 11 Scanner s = new Scanner(new BufferedInputStream(System.in)); 12 n = s.nextInt(); 13 int m = s.nextInt(),k, first, second; 14 for (int i = 1; i <= n; i++) { 15 arr[i] = s.nextLong(); 16 arr[i] += arr[i - 1]; 17 } 18 while (m-- != 0) { 19 order = s.next(); 20 21 if (order.equals("Q")) { //区间查询 22 first = s.nextInt(); 23 second = s.nextInt(); 24 sun = arr[second]-arr[first-1]+(second+1)*query(second, c1)-first*query(first-1, c1)-query(second, c2)+query(first-1, c2); 25 System.out.println(sun); 26 } else { //区间更新 27 first = s.nextInt(); 28 second = s.nextInt(); 29 k = s .nextInt(); 30 Add(first,k,c1); 31 Add(second+1,-k,c1); 32 Add(first,k*first,c2); 33 Add(second+1,-k*(second+1),c2); 34 35 36 } 37 } 38 s.close(); 39 } 40 static long query(int k, long c[]) 41 { 42 long ans=0; 43 while(k>0) { 44 ans += c[k]; 45 k -= lowbit(k); 46 } 47 return ans; 48 } 49 50 static void Add(int k, int change, long c[]) 51 { 52 while(k <= n) { 53 c[k] += change; 54 k += lowbit(k); 55 } 56 } 57 static int lowbit(int x) { 58 return -x & x; 59 } 60 }