线段树区间覆盖问题,主要难点在于lazy标签要怎么用,我们可以定义lazy标签标示对于根节点now来说,他的整个区间也就是[now.l,now.r]是以now.lazy为首项的等差数列,以及作为区间覆盖的标准的话,那这道题和普通的区间覆盖就没有区别了,当然还有别的做法。

#include<iostream>
using namespace std;
const int N=2e5+10;
typedef long long ll;
struct node
{
    int l,r;
    ll v,lazy;
}tree[4*N];
int n,m;
ll getnum(ll x,ll len)
{
    ll ans=0;
    ans=(x+x+len-1)*len/2;
    return ans;
}
void build(int l,int r,int now)
{
    tree[now].l=l;
    tree[now].r=r;
    int mid=(l+r)/2;
    if(l==r){
        cin>>tree[now].v;return;
    }
    else{
        build(l,mid,now*2);
        build(mid+1,r,now*2+1);
    }
    tree[now].v=tree[now*2].v+tree[now*2+1].v;
    return;
}
void pushdown(int now)
{
    int mid=(tree[now].l+tree[now].r)/2;
    int num=tree[now].lazy;
    int l=tree[now].l;
    int r=tree[now].r;
    tree[2*now].v=getnum(num,mid-l+1);
    tree[2*now].lazy=num;
    tree[2*now+1].v=getnum(num+mid+1-l,r-mid);
    tree[2*now+1].lazy=num+mid+1-l;
    tree[now].lazy=0;
    return;
}
void update(int num,int l,int r,int now)
{
    // cout<<l<<" "<<r<<endl;
    int mid=(tree[now].l+tree[now].r)/2;
    if(tree[now].l==l&&tree[now].r==r)
    {
        tree[now].v=ll(num+num+r-l)*(r-l+1)/2;
        tree[now].lazy=num;
        return;
    }
    if(tree[now].lazy!=0)pushdown(now);
    if(r<=mid)update(num,l,r,2*now);
    else if(l>=mid+1)update(num,l,r,2*now+1);
    else
    {
        update(num,l,mid,2*now);
        update(num+mid+1-l,mid+1,r,2*now+1);
    }
    tree[now].v=tree[2*now].v+tree[2*now+1].v;
    return;
}
ll getsum(int l,int r,int now)
{
    int mid=(tree[now].l+tree[now].r)/2;
    if(tree[now].l==l&&tree[now].r==r)return tree[now].v;
    if(tree[now].lazy!=0)pushdown(now);
    ll ans=0;
    if(r<=mid)ans+=getsum(l,r,2*now);
    else if(l>=mid+1)ans+=getsum(l,r,2*now+1);
    else ans+=getsum(l,mid,2*now)+getsum(mid+1,r,2*now+1);
    return ans;
}
int main ()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin>>n>>m;
    build(1,n,1);//建树
    int op,l,r,k;
    while(m--)
    {
        cin>>op;
        if(op==1)
        {
            cin>>l>>r>>k;
            update(k,l,r,1);
        }
        else
        {
            cin>>l>>r;
            cout<<getsum(l,r,1)<<endl;
        }
    }
}