这个可以用树状数组解决但是如果将一个区间的数字全部改为c一般只能用线段树
//线段树
#include<stdio.h>
#include<iostream>
using namespace std;
int a[100005];
int d[100005],b[100005];
inline void pushup(int p){
d[p] = d[p<<1] + d[(p<<1)|1];
return ;
}
inline void pushdown(int s,int t,int p)
{
int mid = (s + t) >> 1;
d[p<<1]+=(mid - s + 1) * b[p];
d[(p<<1)|1] += (t - mid) * b[p];
b[p<<1] = b[p];
b[(p<<1)|1] = b[p];
b[p] = 0;
}
void build(int l,int r,int p){
if(l == r){
d[p] = a[l];
return ;
}
int mid = (l + r)>>1;
build(l,mid,p<<1);
build(mid + 1,r,p<<1|1);
pushup(p);
}
inline void update(int l,int r,int c,int s,int t,int p){
if(l <= s && t <= r){
d[p] += (t - s + 1) *c;
b[p] += c;
return ;
}
if(b[p])pushdown(s,t,p);
int mid = (s + t)>>1;
if(l <= mid)update(l,r,c,s,mid,p<<1);
if(r > mid)update(l,r,c,mid + 1,t,p<<1|1);
pushup(p);
}
inline int getans(int l,int r,int s,int t,int p)
{
int ans = 0;
if(l <= s&&t <= r){
return d[p];
}
//printf("%d %d\n",s,t);
int mid = (s + t)>>1;
// printf("%d\n",mid);
if(b[p])pushdown(s,t,p);
if(l <= mid)ans += getans(l,r,s,mid,p<<1);
if(r > mid)ans += getans(l,r,mid + 1,t,p<<1|1);
pushup(p);
return ans;
}
int main()
{
int n;
scanf("%d",&n);
for(int i = 1;i <= n;i++){
scanf("%d",&a[i]);
}
build(1,n,1);
int m;
scanf("%d",&m);
for(int i = 0;i < m;i++){
int opt;
scanf("%d",&opt);
if(opt == 1){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
update(a,b,c,1,n,1);
}
else{
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",getans(a,b,1,n,1));
}
}
}