POJ 3468 A Simple Problem with Integers

//
//  main.cpp
//  Richard
//
//  Created by 邵金杰 on 16/7/24.
//  Copyright © 2016年 邵金杰. All rights reserved.
//


#include<cstdio>
const int maxn=200000+100;
int nCount=0;
struct CNode{
    int L,R;
    CNode *pLeft,*pRight;
    long long nSum;
    long long Inc;
};
CNode tree[maxn];
int mid(CNode *p)
{
    return (p->L+p->R)/2;
}
void Build(CNode *p,int L,int R)
{
    p->L=L;
    p->R=R;
    p->nSum=0;
    p->Inc=0;
    if(L==R) return ;
    nCount++;
    p->pLeft=tree+nCount;
    nCount++;
    p->pRight=tree+nCount;
    Build(p->pLeft,L,mid(p));
    Build(p->pRight,mid(p)+1,R);
}
void Insert(CNode *p,int i,int v)
{
    if(p->L==i&&p->R==i){
        p->nSum=v;
        return ;
    }
    p->nSum+=v;
    if(i<=mid(p)) Insert(p->pLeft,i,v);
    else Insert(p->pRight,i,v);
}
void Add(CNode *p,int a,int b,long long c)
{
    if(p->L==a&&p->R==b){
        p->Inc+=c;
        return ;
    }
    p->nSum+=(b-a+1)*c;
    if(b<=mid(p)) Add(p->pLeft,a,b,c);
    else if(a>mid(p)) Add(p->pRight,a,b,c);
    else{
        Add(p->pLeft,a,mid(p),c);
        Add(p->pRight,mid(p)+1,b,c);
    }
}
long long Query(CNode *p,int a,int b)
{
    if(p->L==a&&p->R==b){
        return p->nSum+p->Inc*(p->R-p->L+1);
    }
    p->nSum+=p->Inc*(p->R-p->L+1);
    Add(p->pLeft,p->L,mid(p),p->Inc);
    Add(p->pRight,mid(p)+1,p->R,p->Inc);
    p->Inc=0;
    if(b<=mid(p)) return Query(p->pLeft,a,b);
    else if(a>mid(p)) return Query(p->pRight,a,b);
    else{
        return Query(p->pLeft,a,mid(p))+Query(p->pRight,mid(p)+1,b);
    }
}
int main()
{
    int n,q,u,v,l;
    char cmd[10];
    scanf("%d%d",&n,&q);
    Build(tree,1,n);
    for(int i=1;i<=n;i++){
        scanf("%d",&u);
        Insert(tree,i,u);
    }
    while(q--)
    {
        scanf("%s",cmd);
        if(cmd[0]=='Q'){
            scanf("%d%d",&u,&v);
            printf("%lld\n",Query(tree,u,v));
        }
        else{
            scanf("%d%d%d",&u,&v,&l);
            Add(tree,u,v,l);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值