本蒟蒻刚学线段树,求各位神犇优化一下
#include <bits/stdc++.h>
using namespace std;
#define ll unsigned long long
ll tree[300000], k[100001], n, m;
ll read()
{
char c=getchar();ll s=0;int f=1;
while(c<'0'||c>'9')
{
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
s=s*10+c-'0';
c=getchar();
}
return s*f;
}
void build(int l, int r, int p=1)
{
if(l==r)
{
tree[p]=k[l];
return;
}
int mid=(l+r)/2;
build(l, mid, p*2);
build(mid+1, r, p*2+1);
tree[p]=tree[p*2]+tree[p*2+1];
}
void add(int l, int r, int nl, int nr, int num, int p=1)
{
if(l==r&&l>=nl&&r<=nr)
{
tree[p]+=num;
k[l]+=num;
return;
}
if(l==r) return;
int mid=(l+r)/2;
add(l, mid, nl, nr, num, p*2);
add(mid+1, r, nl, nr, num, p*2+1);
tree[p]=tree[p*2]+tree[p*2+1];
}
ll query(int l, int r, int nl, int nr, int p=1)
{
if(l>=nl&&r<=nr) return tree[p];
if((l<nl&&r<nl)||(r>nr&&l>nr)) return 0;
int mid=(l+r)/2;ll sum=0;
sum+=query(l, mid, nl, nr, p*2);
sum+=query(mid+1, r, nl, nr, p*2+1);
return sum;
}
int main()
{
n=read(), m=read();
int a, b, c, d;
for(int i=1;i<=n;i++)
{
k[i]=read();
}build(1, n);
for(int i=1;i<=m;i++)
{
a=read();
if(a==1)
{
b=read(), c=read(), d=read();
add(1, n, b, c, d);
}
else if(a==2)
{
b=read(), c=read();
cout<<query(1, n, b, c)<<endl;
}
}
return 0;
}