这题刚开始用的普通的累加方法,果断超时...中间做些小改变就行了,还有就是结果要用long long
题目链接 点击打开链接
代码注释:
<strong><span style="font-size:18px;color:#ff6600;">#include<iostream>
#include<cstdio>
#define N 100000
using namespace std;
int s[N+5];
struct node
{
int l,r;
long long sum,n; //数比较大用 long long
} a[N*3];
void build(int l,int r,int i)
{
a[i].l=l;
a[i].r=r;
a[i].n=0;
if(l==r)
{
a[i].sum=s[l];
return ;
}
int mid=(l+r)/2;
build(l,mid,2*i);
build(mid+1,r,2*i+1);
a[i].sum=a[2*i].sum+a[2*i+1].sum;//向上更新
}
void insert(int l,int r,int c,int i)
{
if(a[i].l==l&&a[i].r==r)
{
a[i].n+=c;
return;
}
a[i].sum+=(long long)c*(r-l+1); //更新时把每段的总和算出来
int mid=(a[i].l+a[i].r)/2;
if(r<=mid)
insert(l,r,c,2*i);
else if(l>mid)
insert(l,r,c,2*i+1);
else
{
insert(l,mid,c,2*i);
insert(mid+1,r,c,2*i+1);
}
}
long long cal(int l,int r,int i)
{
if(a[i].l==l&&a[i].r==r)
return a[i].sum+(long long)(r-l+1)*a[i].n;
if(a[i].n!=0) // 本题关键就在这,相当于把权值向下传递
{
a[2*i].n+=a[i].n;
a[2*i+1].n+=a[i].n;
a[i].sum+=(long long)(a[i].r-a[i].l+1)*a[i].n;//同上算出每段的sum,最后加起来方便
a[i].n=0;
}
int mid=(a[i].l+a[i].r)/2;
if(r<=mid)
return cal(l,r,2*i);
else if(l>mid)
return cal(l,r,2*i+1);
else
return cal(l,mid,2*i)+cal(mid+1,r,2*i+1);
}
int main()
{
int n,m,x,y,i,c;
while(scanf("%d%d",&n,&m)!=EOF)//用cin可能超时
{
for(i=1; i<=n; i++)
scanf("%d",&s[i]);
build(1,n,1);
char o;
while(m--)
{
getchar(); //这里不要忘了...
scanf("%c",&o);
if(o=='Q')
{
scanf("%d%d",&x,&y);
printf("%lld\n",cal(x,y,1));
}
else
{
scanf("%d%d%d",&x,&y,&c);
insert(x,y,c,1);
}
}
}
}
</span></strong>