树状数组(区间更新,区间查询)

Description

http://poj.org/problem?id=3468

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

The sums may exceed the range of 32-bit integers.

 

#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;
}

 

posted @ 2019-07-31 10:17  无名菜鸟1  阅读(286)  评论(0编辑  收藏  举报