poj 3468 A Simple Problem with Integers 线段树

来源:互联网 发布:西南大学网络教育 答案 编辑:程序博客网 时间:2024/04/29 16:21

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 a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" 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 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4

Sample Output

455915

Hint

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

这道题我没做出来

看了一下poj.pdf 的解题思路

他的解题思路太好了,如下;

在增加时,如果要加的区间正好覆盖一个节点,则增加其节点的Inc值,不再往下走,否则要更新nSum(加上本次增量),再将增量往下传。这样更新的复杂度就是O(log(n))在查询时,如果待查区间不是正好覆盖一个节点,就将节点的Inc往下带,然后将Inc代表的所有增量累加到nSum上后将Inc清0,接下来再往下查询。Inc往下带的过程也是区间分解的过程,复杂度也是O(log(n))

一下为我的代码

#include<stdio.h>
#include<iostream>
using namespace std;
int a[101010];
struct ele
{
    int left;
    int right;
    __int64 sum;
    __int64 value;
}p[505050];
void build(int L,int R,int step)
{
    p[step].left=L;
    p[step].right=R;
    if(L==R)
    {
        p[step].sum=a[L];
        p[step].value=0;
    }


    else
    {
        int Mid=(L+R)/2;
        build(L,Mid,2*step);
        build(Mid+1,R,2*step+1);
        p[step].sum=p[2*step].sum+p[2*step+1].sum;
        p[step].value=0;
    }
}
__int64 Find(int x,int y,int step)
{
    if(p[step].left==x&&p[step].right==y)
        return p[step].sum+p[step].value*(y-x+1);
    else
    {
        p[step].sum=p[step].sum+(p[step].right-p[step].left+1)*p[step].value;
        p[2*step].value=p[2*step].value+p[step].value;
        p[2*step+1].value=p[2*step+1].value+p[step].value;
        p[step].value=0;
        int Mid=(p[step].left+p[step].right)/2;
        if(y<=Mid)
            return Find(x,y,2*step);
        else
        if(x>=Mid+1)
            return Find(x,y,2*step+1);
        else
            return Find(x,Mid,2*step)+Find(Mid+1,y,2*step+1);


    }
}
void update(int x,int y,int z,int step)
{
    if(p[step].left==x&&p[step].right==y)
        p[step].value+=z;
    else
    {
        int Mid=(p[step].left+p[step].right)/2;
        if(y<=Mid)
            update(x,y,z,2*step);
        else
        if(x>=Mid+1)
            update(x,y,z,2*step+1);
        else
        {
            update(x,Mid,z,2*step);
            update(Mid+1,y,z,2*step+1);
        }
        p[step].sum+=(y-x+1)*z;
    }
}
int main()
{
    int N,Q;
    int i;
    char c;
    int x,y,z;
    p[0].sum=0;
    scanf("%d%d",&N,&Q);
        for(i=1;i<=N;i++)
            scanf("%d",&a[i]);
        build(1,N,1);
        while(Q--)
        {
           cin>>c;
           if(c=='Q')
           {
               scanf("%d%d",&x,&y);
               printf("%I64d\n",Find(x,y,1));
           }
            else
            {
                scanf("%d%d%d",&x,&y,&z);
                update(x,y,z,1);
            }
        }
    return 0;
}

0 0