其实想了很久,我也不觉得是自己脑子反应慢,因为老会纠结一些奇怪的点..

也许,因此也对算法有了奇怪的理解吧。

#1,lazytag的作用是,在对同一区间进行多次操作再统一提问时,相当于先存操作数,提问时再一并处理。

lazytag下放的尽头是?放到树的某个节点管辖的区间可以被修改的区间完全包含时,就停止了。

所以最后lazytag的下放情况其实是:下放到最大的节点可以完全管到的区间,由多个这样的区间组成。

这个跟普通线段树的查询操作是一样的。

#2.为什么update的时候要pushdown,为什么还要tree[i].sum=tree[i*2].sum+tree....

待填坑。。困了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node{
    ll l,r,sum,lazy;
}tree[1000000];
ll n,m,input[1000000];
void build(ll i,ll l,ll r)
{
    if(l==r)
    {
        tree[i].l=l;
        tree[i].r=r;
        tree[i].sum=input[l];
        return;
    }
    tree[i].lazy=0;
    tree[i].l=l;
    tree[i].r=r;
    ll mid=(l+r)>>1;
    build(i*2,l,mid);
    build(i*2+1,mid+1,r);
    tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
}
void pushdown(ll i)
{
    if(tree[i].lazy!=0)
     {
         tree[i*2].lazy+=tree[i].lazy;
         tree[i*2+1].lazy+=tree[i].lazy;
         ll mid=(tree[i].l+tree[i].r)>>1;
         tree[i*2].sum+=tree[i].lazy*(mid-tree[i].l+1);
         tree[i*2+1].sum+=tree[i].lazy*(tree[i].r-mid);
        tree[i].lazy=0;
      } 
}
void update(ll i,ll l,ll r,ll k)
{
    if(tree[i].l>=l&&tree[i].r<=r)
    {
        tree[i].lazy+=k;
        tree[i].sum+=k*(tree[i].r-tree[i].l+1);
        return;
    }
    
    pushdown(i);
    ll mid=(tree[i].l+tree[i].r)>>1;
    if(tree[i*2].r>=l)
    {
        update(i*2,l,r,k);
    }
    if(tree[i*2+1].l<=r)
    {
        update(i*2+1,l,r,k);
    }
    tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
    return;
 } 
 ll query(ll i,ll l,int r)
 {
     if(tree[i].l>=l&&tree[i].r<=r)
     {
         return tree[i].sum;
     }
     pushdown(i);
     ll ans=0;
     if(tree[i*2].r>=l)
     {
         ans+=query(i*2,l,r);
     }
     if(tree[i*2+1].l<=r)
     {
         ans+=query(i*2+1,l,r);
     }
     return ans;
 }
int main()
{
    /*
    5 5
1 5 4 2 3
2 2 4
1 2 3 2
2 3 4
1 1 5 1
2 1 4
*/
//freopen("9231.in","r",stdin);
    cin>>n>>m;
    for(ll i=1;i<=n;i++)
    {
        scanf("%lld",&input[i]);
    }
    
    
    build(1,1,n);
    
    
    for(ll i=1;i<=m;i++)
    {
        int a;
        cin>>a;
        if(a==2)
        { ll f,t;
          scanf("%lld%lld",&f,&t);
          cout<<query(1,f,t)<<endl;
        }
        else {
            ll from,to,k;
            scanf("%lld%lld%lld",&from,&to,&k);
            update(1,from,to,k);
        }
    }
}