详解:
http://www.cnblogs.com/lcf-2000/p/5866170.html
比线段树更快,也更简洁;
区间修改+单点查询维护差分数组即可;
但区间修改+区间查询需要维护两个树状数组;
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const ll MAXN=100001;
ll n,m,c1[MAXN],c2[MAXN],a[MAXN];
void read(ll &a)
{
char c=getchar();
ll ans=0,flag=0;
while(c<'0' || c>'9')
{
if(c=='-') flag=1;
c=getchar();
}
while(c>='0' && c<='9')
{
ans*=10;
ans+=c-'0';
c=getchar();
}
if(flag) ans=-ans;
else a=ans;
return;
}
void add(ll i,ll x)
{
ll s=i;
while(i<=n)
{
c1[i]+=x;
c2[i]+=s*x;
i+=i&-i;
}
return;
}
ll sum(ll i)
{
ll s=i,ans=0;
while(i)
{
ans+=(s+1)*c1[i]-c2[i];
i-=i&-i;
}
return ans;
}
void solve()
{
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++)
{
read(a[i]);
add(i,a[i]-a[i-1]);
}
ll f,x,y,k;
for(int i=1;i<=m;i++)
{
read(f),read(x),read(y);
if(f==1)
{
read(k);
add(x,k);
add(y+1,-k);
}
else printf("%lld\n",sum(y)-sum(x-1));
}
return;
}
int main()
{
solve();
return 0;
}