题意是这样的
给你n个数 输入n个数为初值 询问Q次(1.把a到b加c 2.输出a到b的和)(数据范围很大 暴力可能超时 用int64处理)
这道题我是用线段树做的 这道题在于开两个数组 一个存当前节点累加和 另一个存总和 注意函数返回值为int64
贴一下AC代码!!!
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define LL(x) (x<<1)
#define RR(x) (x<<1)|1
__int64 hash[4*100000],tree[4*100000],n;
__int64 update(__int64 left,__int64 right,__int64 L,__int64 R,__int64 c,__int64 mark)
{
if(left==L&&right==R)
{
hash[mark]+=c;
tree[mark]+=c*(R-L+1);
return tree[mark];
}
__int64 mid=(right+left)/2;
if(L>mid)
{
tree[mark]=tree[LL(mark)]+update(mid+1,right,L,R,c,RR(mark));
}
else if(R<=mid)
{
tree[mark]=update(left,mid,L,R,c,LL(mark))+tree[RR(mark)];
}
else
{
tree[mark]=update(left,mid,L,mid,c,LL(mark))+update(mid+1,right,mid+1,R,c,RR(mark));
}
return tree[mark];
}
__int64 find(__int64 left,__int64 right,__int64 L,__int64 R,__int64 mark,__int64 leap)
{
__int64 sum=0;
if(left==L&&right==R)
{
sum+=tree[mark]+leap*(R-L+1);
return sum;
}
__int64 mid=(left+right)/2;
if(L>mid)
{
sum+=find(mid+1,right,L,R,RR(mark),leap+hash[mark]);
}
else if(R<=mid)
{
sum+=find(left,mid,L,R,LL(mark),leap+hash[mark]);
}
else
{
sum+=find(left,mid,L,mid,LL(mark),leap+hash[mark])+find(mid+1,right,mid+1,R,RR(mark),leap+hash[mark]);
}
return sum;
}
int main()
{
__int64 i,j,a,b,c,Q;
char str[2];
while(~scanf("%I64d%I64d",&n,&Q))
{
memset(tree,0,sizeof(tree));
memset(hash,0,sizeof(hash));
for(i=1;i<=n;i++)
{
scanf("%I64d",&a);
update(1,n,i,i,a,1);
}
for(i=1;i<=Q;i++)
{
scanf("%s",str);
scanf("%I64d%I64d",&a,&b);
if(str[0]=='Q')
{
printf("%I64d\n",find(1,n,a,b,1,0));
}
else
{
scanf("%I64d",&c);
update(1,n,a,b,c,1);
}
}
}
return 0;
}