最近这几天在学习线段树,这是线段树题,不能一步更新到位,这样会超时,只能成段更新!
wa了我好几次,增量a要用int64,悲剧啊!!!
#include<stdio.h>
#include<stdlib.h>
#define Max 100010
struct node
{
int l,r;
int num;
__int64 a;//要用__int64
__int64 sum;//
}tree[4*Max];
int s[Max];
__int64 max;
void build(int l,int r,int step)
{
tree[step].l=l;
tree[step].r=r;
tree[step].num=0;
tree[step].a=0;
if(tree[step].l==tree[step].r)
{
tree[step].sum=s[l];
return ;
}
int mid=(tree[step].l+tree[step].r)/2;
build(l,mid,step*2);
build(mid+1,r,step*2+1);
tree[step].sum=tree[step*2].sum+tree[step*2+1].sum;
}
void updata(int l,int r,int x,int step)
{
tree[step].sum+=x*((r-l)+1);
if(tree[step].l==l&&tree[step].r==r)//成段更新
{
tree[step].num=1;
tree[step].a+=x;
return ;
}
if(tree[step].num>0)//传递性质给孩子
{
tree[step*2].a+=tree[step].a;
tree[step*2+1].a+=tree[step].a;
tree[step*2].sum+=tree[step].a*((tree[step*2].r-tree[step*2].l)+1);
tree[step*2+1].sum+=tree[step].a*((tree[step*2+1].r-tree[step*2+1].l)+1);
tree[step].num=0;//置为已传递性质
tree[step].a=0;
tree[step*2].num=1;//置为性质还为传递
tree[step*2+1].num=1;//置为性质还为传递
}
int mid=(tree[step].l+tree[step].r)/2;
if(r<=mid)
{
updata(l,r,x,step*2);
}
else
{
if(mid<l)
updata(l,r,x,step*2+1);
else
{
updata(l,mid,x,step*2);
updata(mid+1,r,x,step*2+1);
}
}
}
void compute(int l,int r,int step)
{
if(tree[step].l==l&&tree[step].r==r)
{
max+=tree[step].sum;
return ;
}
if(tree[step].num>0)//传递性质给孩子
{
tree[step*2].a+=tree[step].a;
tree[step*2+1].a+=tree[step].a;
tree[step*2].sum+=tree[step].a*((tree[step*2].r-tree[step*2].l)+1);
tree[step*2+1].sum+=tree[step].a*((tree[step*2+1].r-tree[step*2+1].l)+1);
tree[step].num=0;
tree[step].a=0;
tree[step*2].num=1;
tree[step*2+1].num=1;
}
int mid=(tree[step].r+tree[step].l)/2;
if(r<=mid)
{
compute(l,r,step*2);
}
else
{
if(mid<l)
{
compute(l,r,step*2+1);
}
else
{
compute(l,mid,step*2);
compute(mid+1,r,step*2+1);
}
}
}
int main()
{
//freopen("1.txt","r",stdin);
int n,a,b,m,i;
int c;
char str[5];
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=1;i<=n;i++)
scanf("%d",&s[i]);
build(1,n,1);
while(m--)
{
scanf("%s",&str);
if(str[0]=='C')
{
scanf("%d%d%d",&a,&b,&c);
if(c==0)
continue;
updata(a,b,c,1);
}
else
{
scanf("%d%d",&a,&b);
max=0;
compute(a,b,1);
printf("%I64d\n",max);
}
}
}
return 0;
}