#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200010;
#define int long long
int n,m;
int w[N];
struct node
{
int l,r;
int sum,tag;
}tr[N*4];
int cal(int a1,int len)
{
int an=a1+len-1;
return (a1+an)*len/2;
}
void pushup(int u)
{
tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
}
void pushdown(int u)
{
if(tr[u].tag)
{
tr[u<<1].tag=tr[u].tag;
tr[u<<1|1].tag=tr[u].tag+tr[u<<1].r-tr[u<<1].l+1;
tr[u<<1].sum=cal(tr[u<<1].tag,tr[u<<1].r-tr[u<<1].l+1);
tr[u<<1|1].sum=cal(tr[u<<1|1].tag,tr[u<<1|1].r-tr[u<<1|1].l+1);
tr[u].tag=0;
}
}
void build(int u,int l,int r)
{
if(l==r)tr[u]={l,r,w[l],0};
else
{
tr[u]={l,r};
int mid=l+r>>1;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
pushup(u);
}
}
void modify(int u,int l,int r,int v)
{
if(tr[u].l>=l&&tr[u].r<=r)
{
tr[u].tag=tr[u].l-l+v;
tr[u].sum=cal(tr[u].tag,tr[u].r-tr[u].l+1);
return ;
}
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
if(l<=mid)modify(u<<1,l,r,v);
if(r>mid)modify(u<<1|1,l,r,v);
pushup(u);
}
int query(int u,int l,int r)
{
if(tr[u].l>=l&&tr[u].r<=r)return tr[u].sum;
int res=0;
int mid=tr[u].l+tr[u].r>>1;
pushdown(u);
if(l<=mid)res+=query(u<<1,l,r);
if(r>mid)res+=query(u<<1|1,l,r);
return res;
}
signed main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>w[i];
build(1,1,n);
int op,l,r;
while(m--)
{
cin>>op>>l>>r;
if(op==1)
{
int k;cin>>k;
modify(1,l,r,k);
}
else cout<<query(1,l,r)<<'\n';
}
}
区区区间---线段树lazy标记板子题
最新推荐文章于 2024-07-28 21:35:11 发布