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

题目大意:

给你n个整数,两种操作,

求一段区间的和 

一段区间内全部加上某个整数

简单线段树题

区间内一部分是固定区间和

另一个是此区间内每个数都需要加的量

注意用64为整数

详情见代码注释:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;
const int N=100005;
struct node
{
    int l,r;
    long long add;//非固定,需要向下传递的量
    long long v;//固定住的和
}mem[N*4];
int a[N];
long long ans;
void build(int x,int l,int r)
{
    mem[x].l=l;
    mem[x].r=r;
    mem[x].add=0;//初始化
    if(l==r)
    {
        mem[x].v=a[l];
    }
    else
    {
        int mid=(l+r)>>1;
        build(x*2,l,mid);
        build(x*2+1,mid+1,r);
        mem[x].v=mem[x*2].v+mem[x*2+1].v;
    }
}
void findsum(int x,int i,int j)
{
    if(mem[x].l==i&&mem[x].r==j)
    {
        ans=ans+mem[x].v+(mem[x].r-mem[x].l+1)*mem[x].add;//如果正好是这个区间
    }
    else
    {
        int mid=(mem[x].l+mem[x].r)>>1;
        mem[x].v+=(mem[x].r-mem[x].l+1)*mem[x].add;//否则向下传递,首先本区间固定量增加
        mem[x*2].add+=mem[x].add;mem[x*2+1].add+=mem[x].add;//然后传给左右区间
        mem[x].add=0;//最后清零
        if(j<=mid)
        {
            findsum(x*2,i,j);
        }else if(i>mid)
        {
            findsum(x*2+1,i,j);
        }else
        {
            findsum(x*2,i,mid);
            findsum(x*2+1,mid+1,j);
        }
    }
}
void Addint(int x,int i,int j,int k)
{
    if(mem[x].l==i&&mem[x].r==j)
    {
        mem[x].add+=k;//本区间改变增加量
    }
    else
    {
        mem[x].v+=(j-i+1)*k;//向下的话,首先本区间先将固定量增加
        int mid=(mem[x].l+mem[x].r)>>1;
        if(j<=mid)
        {
            Addint(x*2,i,j,k);
        }else if(i>mid)
        {
            Addint(x*2+1,i,j,k);
        }else
        {
            Addint(x*2,i,mid,k);
            Addint(x*2+1,mid+1,j,k);
        }
    }
}
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=1;i<=n;++i)
        {
            scanf("%d",&a[i]);
        }
        build(1,1,n);
        while(m--)
        {
            char c;
            int i,j,k;
            getchar();//吃换行
            scanf("%c",&c);
            if(c=='Q')
            {
                scanf("%d %d",&i,&j);
                ans=0;
                findsum(1,i,j);
                printf("%I64d\n",ans);
            }
            else
            {
                scanf("%d %d %d",&i,&j,&k);
                Addint(1,i,j,k);
            }
        }
    }
    return 0;
}

  

posted on 2012-06-14 11:24  夜->  阅读(125)  评论(0编辑  收藏  举报