终于写对了的线段树

终于写对了线段树

今天开始了洛谷春令营,然后我因为昨天晚上肝到太晚,结果…8:28才起床,GG。
之后早饭没吃直接开机听课,还好没耽误。
今天上午首先讲的就是线段树的变种,我连线段树还没打出来呢!!!搞什么变种?!不过以前已经看过并理解了线段树的大体思路,所以听起课来还是没有多大障碍的,至于课程的具体内容,晚些时候发篇密码博客总结一下。
于是今天下午吃过饭就开始敲线段树。
一直敲到现在,中间换了无数本资料+看了无数题解,大概勉强找到了和我期望的线段树差不多的题解,写好之后一句一句对照来检查终于算是完事了,结果一运行,一询问直接无响应,最后被逼无奈输出各种中间值,发现是把一个变量写错了,因为当时题解和我的代码用的变量不一样所以没看出来,GG!!!
debug完成后提交洛谷模板题:P3372 【模板】线段树 1终于AC!有生以来第一次写出了完整的线段树(热泪盈眶)!!!
放一下代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=100001,maxm=100001;
long long a[maxn],n,m,x,y,k,mod;
struct node
{
    long long sumv[maxn<<2],addv[maxn<<2];
    inline void pushup(int o)
    {
        sumv[o]=sumv[o<<1]+sumv[o<<1|1];
    }
    inline void pushdown(int o,int l,int r,int s,int t)
    {
        if(!addv[o])return;
        int mid=(l+r)>>1;
        sumv[o<<1]+=addv[o]*(mid-l+1);addv[o<<1]+=addv[o];
        sumv[o<<1|1]+=addv[o]*(r-mid);addv[o<<1|1]+=addv[o];
        addv[o]=0;return;
    }
    inline void build(int o,int l,int r)
    {
        if(l==r)
        {
            sumv[o]=a[l];
            return;
        }
        int mid = (l+r)>>1;
        build(o<<1,l,mid);
        build(o<<1|1,mid+1,r);
        pushup(o);
    }
    inline void optadd(int o,int l,int r,int s,int t,long long v)
    {
        if(l>=s&&r<=t)
        {
            sumv[o]+=v*(r-l+1);
            addv[o]+=v;
            return;
        }
        int mid=(l+r)>>1;
        pushdown(o,l,r,s,t);
        if(s<=mid)optadd(o<<1,l,mid,s,t,v);
        if(t>mid)optadd(o<<1|1,mid+1,r,s,t,v);
        pushup(o);
    }
    long long query(int o,int l,int r,int s,int t)
    {
        if(l>=s&&r<=t)return sumv[o];
        long long ans=0;
        int mid=(l+r)>>1;
        if(addv[o])pushdown(o,l,r,s,t);
        if(s<=mid)
        {
            ans+=query(o<<1,l,mid,s,t);
        }
        if(t>mid)
        {
            ans+=query(o<<1|1,mid+1,r,s,t);
        }
        return ans;
    }
}segtree;
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    segtree.build(1,1,n);
    while(m--)
    {
        scanf("%d",&k);
        if(k==1)
        {
            scanf("%d%d%d",&x,&y,&k);
            segtree.optadd(1,1,n,x,y,k);
        }
        else
        {
            scanf("%d%d",&x,&y);
            long long ans=segtree.query(1,1,n,x,y);
            printf("%lld\n",ans);
        }
    }
    return 0;
}