- 数列操作c
★★ 输入文件:shuliec.in 输出文件:shuliec.out 简单对比
时间限制:1 s 内存限制:128 MB
所有答案小于4611686018427387904
【问题描述】
假设有一列数 {Ai }(1 ≤ i ≤ n),n<=100000 ,支持如下两种操作:
(1)将 A i至A j 的值均增加 D 。( i,j,D 是输入的数)
(2) 输出 A s +A s+1 +…+A t 。( s, t 都是输入的数, S ≤ T )
根据操作要求进行正确操作并输出结果。
【输入格式】
输入文件第一行一个整数 n ,
第二行为 n 个整数,表示 {A i } 的初始值。
第三行为一个整数 m ,表示操作数
v 下接 m 行,每行描述一个操作,有如下两种情况:
ADD i j d ( 表示将 A i至A j 的值均增加 D , 1<=i,j<=n , d 为整数 )
SUM s t (表示输出 A s +…+A t )
【输出格式】
对于每一个 SUM 提问,输出结果
【输入输出样例】
输入:
shuliec.in
4
1 4 2 3
3
SUM 1 3
ADD 2 2 50
SUM 2 3
输出:
shuliec.out
7
56
分析:模板
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<string>
#define SpeedUp ios::sync_with_stdio(false)
using namespace std;
struct TREE{
long long sum;
int l;
int r;
long long delta;
TREE *lc,*rc;
TREE():sum(0),delta(0){}
};
int n,m;
long long a[1000000];
void update(TREE *p)
{
p->lc->sum+=p->delta*(p->lc->r-p->lc->l);
p->rc->sum+=p->delta*(p->rc->r-p->rc->l);
p->lc->delta+=p->delta;
p->rc->delta+=p->delta;
p->delta=0;
}
void build(TREE *p,int l,int r){
p->l=l;
p->r=r;
if (l+1==r)
{
p->sum=a[l];
p->lc=NULL;
p->rc=NULL;
return;
}
else if (l+1<r)
{
p->lc=new TREE;
p->rc=new TREE;
build(p->lc,l,(l+r)/2);
build(p->rc,(l+r)/2,r);
p->sum=p->lc->sum+p->rc->sum;
return;
}
return;
}
void change(TREE *p,int l,int r,long long delta){
if (l<=p->l&&p->r<=r)
{
p->sum+=delta*(p->r-p->l);
p->delta+=delta;
}
else
{
if (p->delta!=0)
{
update(p);
}
if (l<(p->l+p->r)/2)
change(p->lc,l,r,delta);
if (r>(p->l+p->r)/2)
change(p->rc,l,r,delta);
p->sum=p->lc->sum+p->rc->sum;
}
}
long long Q(TREE *p,int l,int r){
if (l<=p->l&&p->r<=r) return p->sum;
else
{
if (p->delta!=0)
{
update(p);
}
long long ans=0;
if (l<(p->l+p->r)/2)
{
ans+=Q(p->lc,l,r);
}
if (r>(p->l+p->r)/2)
{
ans+=Q(p->rc,l,r);
}
return ans;
}
}
int main()
{
freopen("shuliec.in","r",stdin);
freopen("shuliec.out","w",stdout);
SpeedUp;
cin>>n;
int x,y,z;
TREE *root=new TREE;
for (int i=1;i<=n;++i)
{
cin>>a[i];
}
build(root,1,n+1);
cin>>m;
for (int i=1;i<=m;++i)
{
char op[8];
long long x,y,z;
cin>>op;
if(op[0]=='A')
{
cin>>y>>z>>x;
change(root,y,z+1,x);
}
else if (op[0]=='S')
{
cin>>x>>y;
cout<<Q(root,x,y+1)<<endl;
}
}
return 0;
}