我就知道我的线段树一定会超时的。。。。qwq
最后三个点T了,到底哪些函数是没必要或者是可以优化的啊qwq
#include <iostream>
#include <cstdio>
using namespace std;
long long n,m,a[1000000],t,x,y,k;
struct gs
{
long long l,r,num,j;
}shu[1000000];
void build(long long g,long long l,long long r)
{
shu[g].l=l;
shu[g].r=r;
if(l==r)
{
shu[g].num=a[l];
return ;
}
long long mid=(l+r)/2;
build(g*2,l,mid);
build(g*2+1,mid+1,r);
shu[g].num=shu[g*2].num+shu[g*2+1].num;
return ;
}
void sh(long long g,long long num)//向上更新 区间和
{
if(g==0) return ;
shu[g].num+=num;
sh(g/2,num);
}
void cd(long long g)//向下传递要加的标记
{
if(shu[g].l==shu[g].r) {shu[g].num+=shu[g].j;sh(g/2,shu[g].j);shu[g].j=0;return ;}
shu[g*2].j+=shu[g].j;
shu[g*2+1].j+=shu[g].j;
shu[g].j=0;
cd(g*2);
cd(g*2+1);
}
void jia(long long g,long long l,long long r,long long num)//区间加
{
if(shu[g].l>r||shu[g].r<l) return ;
if(shu[g].l>=l&&shu[g].r<=r) {shu[g].j+=num;cd(g);return ;}
long long mid=(shu[g].l+shu[g].r)/2;
if(l<=mid) jia(g*2,l,r,num);
if(r>mid) jia(g*2+1,l,r,num);
return ;
}
long long count(long long g,long long l,long long r,long long ans)//输出区间的值
{
if(shu[g].l>r||shu[g].r<l) return 0;
if(shu[g].l>=l&&shu[g].r<=r) {ans+=shu[g].num;/*cout<<endl<<g<<endl;*/return ans;}
long long mid=(shu[g].l+shu[g].r)/2;
if(l<=mid) ans+=count(g*2,l,r,0);
if(r>mid) ans+=count(g*2+1,l,r,0);
return ans;
}
int main()
{
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,1,n);
for(int i=1;i<=m;i++)
{
scanf("%lld",&t);
if(t==1)
{
scanf("%lld%lld%lld",&x,&y,&k);
jia(1,x,y,k);
}
if(t==2)
{
scanf("%lld%lld",&x,&y);
printf("%lld\n",count(1,x,y,0));
}
}
return 0;
}