树状数组(区间更新,区间查询)
Posted nonames
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树状数组(区间更新,区间查询)相关的知识,希望对你有一定的参考价值。
Description
You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.
Input
The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.
Output
You need to answer all Q commands in order. One answer in a line.
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
Hint
#include <iostream> #include <iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #include <stdio.h> #include <string.h> #define rep(i , n) for(int i = 0 ; i < (n) ; i++) using namespace std; const int N = 1000010 ; long long ans = 0 , flag = 1; long long a[200009] , sum1[200009] , sum2[200009];//sum1´æ²î·ÖD[i] £¬ sum2´æ(n-1)*D[i]; /* = (D[1]) + (D[1]+D[2]) + ... + (D[1]+D[2]+...+D[n]) = n*D[1] + (n-1)*D[2] +... +D[n] = n * (D[1]+D[2]+...+D[n]) - (0*D[1]+1*D[2]+...+(n-1)*D[n]) sum1[i] = D[i],sum2[i] = D[i]*(i-1) */ long long n , q ; char c[5]; long long lowerbit(long long x) return x&(-x) ; void update(long long x , long long value) long long m = x ; for(long long i = x ; i <= n ; i += lowerbit(i)) sum1[i] += value ; sum2[i] += value * (m-1); long long getsum(long long x) long long ans = 0 ; long long m = x ; for(int i = x ; i > 0 ; i -= lowerbit(i)) ans += sum1[i] * m - sum2[i]; return ans ; int main() while(~scanf("%lld%lld" , &n , &q)) memset(a , 0 , sizeof(a)); for(int i = 1 ; i <= n ; i++) scanf("%lld" , &a[i]); update(i , a[i] - a[i-1]); for(int i = 0 ; i < q ; i++) scanf("%s" , c); if(c[0] == ‘Q‘) long long l , r ; scanf("%lld%lld" , &l , &r); cout << getsum(r) - getsum(l-1) << endl ; else long long l , r , addval; scanf("%lld%lld%lld" , &l , &r , &addval); update(l , addval); update(r + 1 , -addval); return 0;
以上是关于树状数组(区间更新,区间查询)的主要内容,如果未能解决你的问题,请参考以下文章