点我看题目

 

题意  :N个数Q条命令,Q a b代表输入AaAa+1, ... , Ab的和。a b c代表让你把c加给AaAa+1, ... , Ab的每一个数。

思路 :这个题分类好像不是线段树。。不过我硬是按线段树的方法做了,总觉得和HDU1166和1754差不多,反正要注意数据范围很大不能用int,我还因为用了intWA了一次。反正比平时那些模板的更新啊加减什么的都比较麻烦。

#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

const int maxn = 5000004 ;
typedef long long  LL;
struct node
{
    int l,r ;
    LL sum,add ;
    int boundary ;
} Node[maxn] ;
int a[maxn] ;

void build(int v,int  l,int r)
{
    Node[v].l = l ;
    Node[v].r = r ;
    Node[v].boundary = (l+r)/2 ;
    Node[v].add = 0 ;
    if(l == r)
    {
        Node[v].sum = a[l] ;
        return ;
    }
    int mid = (l+r)>>1 ;
    build(v*2,l,mid) ;
    build(v*2+1,mid+1,r) ;
    Node[v].sum = Node[v*2].sum + Node[v*2+1].sum ;
}

void update(int v,int value,int l,int r)
{
    if(Node[v].l == l && Node[v].r == r)
    {
        Node[v].add += value ;
        return ;
    }
    Node[v].sum += (LL)(value*(1+r-l)) ;
    if(Node[v].boundary >= r)
        update(v*2,value,l,r) ;
    else if(Node[v].boundary < l)
        update(v*2+1,value,l,r) ;
    else
    {
        update(v*2,value,l,Node[v].boundary) ;
        update(v*2+1,value,Node[v].boundary+1,r) ;
    }
}
LL query(int v,int l,int r)
{
    if(Node[v].l == l && Node[v].r == r)
    {
        return Node[v].sum + Node[v].add*(LL)(r-l+1) ;
    }
    if(Node[v].add != 0)
    {
        Node[v*2].add += Node[v].add ;
        Node[v*2+1].add += Node[v].add ;
        Node[v].sum += (LL)(Node[v].r-Node[v].l+1)*Node[v].add ;
        Node[v].add = 0 ;
    }
    if(Node[v].boundary >= r)
        return query(v*2,l,r) ;
    else if(Node[v].boundary < l)
        return query(v*2+1,l,r) ;
    else return query(v*2,l,Node[v].boundary)+query(v*2+1,Node[v].boundary+1,r) ;
}

int main()
{
    int m,n ;
    while(~scanf("%d %d",&n,&m))
    {
        for(int i = 1 ; i <= n ; i++ )
        {
            scanf("%d",&a[i]) ;
        }
        int x,y,z ;
        build(1,1,n) ;
        char str[54] ;
        for(int i = 1 ; i <= m ; i++)
        {
            scanf("%s",str) ;
            if(str[0] == 'Q')
            {
                scanf("%d %d",&x,&y) ;
                printf("%lld\n",query(1,x,y)) ;
            }
            if(str[0] == 'C')
            {
                scanf("%d %d %d",&x,&y,&z) ;
                update(1,z,x,y) ;
            }
        }
    }
    return 0;
}
View Code

 



posted on 2014-02-20 21:00  枫、  阅读(224)  评论(0编辑  收藏  举报