poj 3468

题意  两种操作 1:区间更新c

                    2:问区间的和

      经典区间线段树

#include <iostream>
#include<stdio.h>
using namespace std;
const int N=100011;
struct Node
{
    int l,r;
    __int64 s,sum;
}Tree[N*4];
void Build(int root,int l,int r)
{
    Tree[root].s=0;
    Tree[root].l=l;Tree[root].r=r;
    if(l==r)
    {
        scanf("%I64d",&Tree[root].sum);return ;
    }
    Build(root*2,l,(l+r)/2);
    Build(root*2+1,(l+r)/2+1,r);
    Tree[root].sum=Tree[root*2].sum+Tree[root*2+1].sum;
}
void pushdown(int root)
{
    Tree[root].sum+=Tree[root].s*(Tree[root].r-Tree[root].l+1);
    Tree[root*2].s+=Tree[root].s;
    Tree[root*2+1].s+=Tree[root].s;
    Tree[root].s=0;
}
__int64 Query(int root,int l,int r)//查询 l-->r区间的和
{
    if(Tree[root].l==l&&Tree[root].r==r)
        return (Tree[root].r-Tree[root].l+1)*Tree[root].s+Tree[root].sum;//节点的sum值保存的是 孩子节点的所有 lazy 与sum的值 而不保存当前节点的lazy值
    if(Tree[root].s)//在查询的时候向下推  
        pushdown(root);//查询的时候则必须pushdown与 区间覆盖恰恰相反;
    int mid=(Tree[root].l+Tree[root].r)/2;
    if(r<=mid)
        return Query(root*2,l,r);
    else if(l>mid)
        return Query(root*2+1,l,r);
    else return Query(root*2,l,mid)+Query(root*2+1,mid+1,r);
}
void Updata(int root,int l,int r,__int64 c)
{
    if(Tree[root].l==l&&Tree[root].r==r)
    {
        Tree[root].s+=c;
        return ;
    }
    Tree[root].sum+=c*(r-l+1);//所过祖先节点 肯定包括当前要插入的区间  因此 不需要pushdown;采取了从上向下的更新方式;
    int mid=(Tree[root].l+Tree[root].r)/2;
    if(r<=mid)
         Updata(root*2,l,r,c);
    else if(l>mid)
        return Updata(root*2+1,l,r,c);
    else
    {
         Updata(root*2,l,mid,c);
         Updata(root*2+1,mid+1,r,c);
    }
}
int main()
{
    char str[11];
    int n,m,a,b;
    __int64 d;
    while(scanf("%d%d",&n,&m)!=EOF)
    {

        Build(1,1,n);
        while(m--)
        {
            scanf("%s",str);
            if(str[0]=='Q')
            {
                scanf("%d%d",&a,&b);
                printf("%I64d\n",Query(1,a,b));
            }
            else
            {
                scanf("%d%d%I64d",&a,&b,&d);
                Updata(1,a,b,d);
            }
        }
    }
    return 0;
}

 

posted @ 2015-03-19 20:30  _一千零一夜  阅读(134)  评论(0编辑  收藏  举报