好气啊,因query和change的函数l,r返回值报错憋了5分钟,下次一定注意
long long暴力美学
这份代码写的还是很美观的
#include<bits/stdc++.h>
using namespace std;
const long long maxn=1e5+1;
long long n,m,a[maxn];
struct T
{
long long data,add,l,r;
}node[4*maxn];
void build(long long pos,long long l,long long r)
{
node[pos].l=l;
node[pos].r=r;
if(l==r)
{
node[pos].data=a[l];
return;
}
long long mid=(l+r)>>1;
build(pos<<1,l,mid);
build(pos<<1|1,mid+1,r);
node[pos].data=node[pos<<1].data+node[pos<<1|1].data;
}
void pushdown(long long pos)
{
if(node[pos].add)
{
node[pos<<1].data+=node[pos].add*(node[pos<<1].r-node[pos<<1].l+1);
node[pos<<1|1].data+=node[pos].add*(node[pos<<1|1].r-node[pos<<1|1].l+1);
node[pos<<1].add+=node[pos].add;
node[pos<<1|1].add+=node[pos].add;
node[pos].add=0;
}
}
void change(long long pos,long long l,long long r,long long v)
{
if(l<=node[pos].l&&node[pos].r<=r)
{
node[pos].add+=v;
node[pos].data+=v*(node[pos].r-node[pos].l+1);
return;
}
pushdown(pos);
long long mid=(node[pos].l+node[pos].r)>>1;
if(l<=mid) change(pos<<1,l,r,v);
if(r>mid) change(pos<<1|1,l,r,v);
node[pos].data=node[pos<<1].data+node[pos<<1|1].data;
}
long long query(long long pos,long long l,long long r)
{
if(l<=node[pos].l&&node[pos].r<=r)
{
return node[pos].data;
}
pushdown(pos);
long long mid=(node[pos].l+node[pos].r)>>1,answer=0;
if(l<=mid) answer+=query(pos<<1,l,r);
if(r>mid) answer+=query(pos<<1|1,l,r);
return answer;
}
int main()
{
scanf("%lld%lld",&n,&m);
memset(a,0,sizeof(a));
for(long long i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,1,n);
for(long long i=1;i<=m;i++)
{
long long a;
scanf("%lld",&a);
if(a==1)
{
long long b,c,d;
scanf("%lld%lld%lld",&b,&c,&d);
change(1,b,c,d);
}
else
{
long long b,c;
scanf("%lld%lld",&b,&c);
printf("%lld\n",query(1,b,c));
}
}
return 0;
}