poj 3468 (線段樹區間更新及求和)

 A Simple Problem with Integers
Time Limit:5000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I64u

Description

You have N integers, A1A2, ... , 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 A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C abc" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q ab" means querying the sum of AaAa+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 <cstdio>
# include <iostream>
# define MN 400000
using namespace std;
long long a[100005];
struct node{
	int left,right,mid;
	long long add,x;
}tree[MN];

void build(int le,int ri,int num)//構建一個線段樹
{
    tree[num].left= le;
    tree[num].right = ri;
    tree[num].add = 0;
    tree[num].mid = (le + ri) /2;
    if(le!=ri)
    {
        build(le,tree[num].mid,num*2);
        build(tree[num].mid+1,ri,num*2+1);
        tree[num].x=tree[num*2].x+tree[num*2+1].x;
    }
    else
    {
        tree[num].x=a[le];
        return ;
    }
}

void change(int le,int ri,int num,int cha)//在一段連續的序列裏改變數值
{

    if(tree[num].left==le&&tree[num].right==ri)
    {
        tree[num].add += cha;
        tree[num].x += cha*(ri-le+1);
        return ;
    }
    if(tree[num].add)
    {
        tree[num*2].add+=tree[num].add;//將加的數傳下去
        tree[num*2+1].add += tree[num].add;
        tree[2*num].x += tree[num].add*(tree[2*num].right-tree[2*num].left+1);
        tree[2*num+1].x += tree[num].add*(tree[2*num+1].right-tree[2*num+1].left+1);
        tree[num].add=0;
    }
    if(ri<=tree[num].mid)
        change(le,ri,num*2,cha);
    else if(le>tree[num].mid)
        change(le,ri,num*2+1,cha);
    else
    {
        change(le,tree[num].mid,num*2,cha);
        change(tree[num].mid+1,ri,num*2+1,cha);
    }
    tree[num].x=(tree[num*2].x + tree[num*2+1].x);
//    cout<<"tree["<<num<<"].x"<<tree[num].x<<endl;
}

long long getsum(int le,int ri,int num)// 求和
{
    if (le==tree[num].left && ri==tree[num].right)
        return tree[num].x ;             // 找到,返回
    if(tree[num].add)
    {

        tree[2*num].add += tree[num].add;
        tree[2*num+1].add += tree[num].add;
        tree[2*num].x += tree[num].add*(tree[2*num].right-tree[2*num].left+1);
        tree[2*num+1].x += tree[num].add*(tree[2*num+1].right-tree[2*num+1].left+1);
        tree[num].add = 0;
    }

    if(le>tree[num].mid)
        return getsum(le,ri,2*num+1);
    else if(ri<=tree[num].mid)
        return getsum(le,ri,2*num);
    else
    {
        return getsum(le,tree[num].mid,2*num)+getsum(tree[num].mid+1,ri,2*num+1);
    }
}

int main()
{
    int N,Q,i,j;
    while(~scanf("%d %d",&N,&Q))
    {
        for (i=1;i<=N;i++)
           scanf("%lld",&a[i]);
        getchar();
        build(1,N,1);
        char T;
        int m,t,l,r,c;
        for (j=Q;j>0;j--)
        {
            scanf("%c",&T);
            if(T=='Q')
            {
                scanf("%d%d",&l,&r);
                getchar();
                cout << getsum(l,r,1) << endl;
            }
            else {
                scanf("%d%d%d",&l,&r,&m);
                getchar();
                change(l,r,1,m);
            }
        }
    }
    return 0;

}
/*

10 22
1 2 3 4 5 6 7 8 9 10
Q 4 4
C 1 10 3
C 6 10 3
C 6 9 3
C 8 9 -100
C 7 9 3
C 7 10 3
C 1 10 3
Q 6 10
Q 6 9
Q 8 9
Q 7 9
Q 7 10
Q 1 10
Q 2 4
C 3 6 3
Q 9 9
Q 1 1
Q 5 5
Q 6 6
Q 7 7
Q 6 8
4
-82
-104
-147
-122
-100
-37
27
-73
7
14
21
25
-28
*/


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章