2 条题解

  • 2
    @ 2017-11-04 16:54:53
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iomanip>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <deque>
    #include <set>
    #include <limits>
    #include <string>
    #include <sstream>
    using namespace std;
    
    long long n,m,st_size;
    long long a[3000000+1];
    long long st_t[3000000+1];
    long long st_l[3000000+1];
    long long st_r[3000000+1];
    long long st_mid[3000000+1];
    long long st_lc[3000000+1];
    long long st_rc[3000000+1];
    long long st_sum[3000000+1];
    long long st_lazy[3000000+1];
    
    void push_up_1(long long now)
    {
        st_sum[now]=st_sum[st_lc[now]]+st_sum[st_rc[now]]+((st_r[now]-st_l[now]+1)*st_lazy[now]);
    }
    
    void build_st_1(long long &now,long long l,long long r)
    {
        now=++st_size;
        st_l[now]=l;
        st_r[now]=r;
        st_mid[now]=(l+r)/2;
        if (l==r)
            st_sum[now]=a[l];
        else if (l<r)
        {
            if (l<=st_mid[now])
                build_st_1(st_lc[now],l,st_mid[now]);
            if (st_mid[now]+1<=r)
                build_st_1(st_rc[now],st_mid[now]+1,r);
            push_up_1(now);
        }
    }
    
    void copy_1(long long now,long long last)
    {
        st_l[now]=st_l[last];
        st_r[now]=st_r[last];
        st_mid[now]=st_mid[last];
        st_lc[now]=st_lc[last];
        st_rc[now]=st_rc[last];
        st_sum[now]=st_sum[last];
        st_lazy[now]=st_lazy[last];
    }
    
    void update_st_1(long long &now,long long last,long long l,long long r,long long d)
    {
        now=++st_size;
        copy_1(now,last);
        if (st_l[now]==l&&r==st_r[now])
        {
            st_sum[now]+=((r-l+1)*d);
            st_lazy[now]+=d;
        }
        else
        {
            if (r<=st_mid[now])
                update_st_1(st_lc[now],st_lc[last],l,r,d);
            else if (st_mid[now]+1<=l)
                update_st_1(st_rc[now],st_rc[last],l,r,d);
            else
            {
                update_st_1(st_lc[now],st_lc[last],l,st_mid[now],d);
                update_st_1(st_rc[now],st_rc[last],st_mid[now]+1,r,d);
            }
            push_up_1(now);
        }
    }
    
    long long ask_st_sum_1(long long now,long long l,long long r,long long lazy_d)
    {
        if (st_l[now]==l&&r==st_r[now])
            return st_sum[now]+((r-l+1)*lazy_d);
        else if (r<=st_mid[now])
            return ask_st_sum_1(st_lc[now],l,r,lazy_d+st_lazy[now]);
        else if (st_mid[now]+1<=l)
            return ask_st_sum_1(st_rc[now],l,r,lazy_d+st_lazy[now]);
        else
            return ask_st_sum_1(st_lc[now],l,st_mid[now],lazy_d+st_lazy[now])+ask_st_sum_1(st_rc[now],st_mid[now]+1,r,lazy_d+st_lazy[now]);
    }
    
    int main()
    {
        while (~scanf("%lld%lld",&n,&m))
        {
            for (long long i=1;i<=n;i++)
                scanf("%lld",&a[i]);
            st_size=0;
            memset(st_t,0,sizeof(st_t));
            memset(st_l,0,sizeof(st_l));
            memset(st_r,0,sizeof(st_r));
            memset(st_mid,0,sizeof(st_mid));
            memset(st_lc,0,sizeof(st_lc));
            memset(st_rc,0,sizeof(st_rc));
            memset(st_sum,0,sizeof(st_sum));
            memset(st_lazy,0,sizeof(st_lazy));
            build_st_1(st_t[st_size],1,n);
            for (long long i=1,tag=0;i<=m;i++)
            {
                char o;
                for (o='$';o!='C'&&o!='Q'&&o!='H'&&o!='B';o=getchar())
                    ;
                if (o=='C')
                {
                    tag++;
                    long long l,r,d;
                    scanf("%lld%lld%lld",&l,&r,&d);
                    update_st_1(st_t[tag],st_t[tag-1],l,r,d);
                }
                else if (o=='Q'||o=='H')
                {
                    long long l,r,t;
                    scanf("%lld%lld",&l,&r);
                    if (o=='H')
                        scanf("%lld",&t);
                    else
                        t=tag;
                    printf("%lld\n",ask_st_sum_1(st_t[t],l,r,0));
                }
                else if (o=='B')
                {
                    long long t;
                    scanf("%lld",&t);
                    tag=t;
                }
            }
        }
    }
    
  • 1
    @ 2020-12-01 11:09:22
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <deque>
    using namespace std;
    
    namespace dts
    {
        typedef long long ll;
        class segtree{
        public:
            ll size=0;
            class st_rec{
            public:
                ll rt,rtl,rtr;
            };
            deque<st_rec> rec;
            deque<ll> fa,lc,rc,sl,sr,smid,sum,sumlz;
            void reszcl(ll sz)
            {
                size=0;
                rec.resize(sz);
                fa.clear(),lc.clear(),rc.clear();
                sl.clear(),sr.clear(),smid.clear();
                sum.clear(),sumlz.clear();
            }
            void set_st(ll ver,ll l,ll r)
            {
                rec[ver].rt=-1,rec[ver].rtl=l,rec[ver].rtr=r;
            }
            ll len(ll now)
            {
                return sr[now]-sl[now]+1;
            }
            void update(ll &now,ll last,ll fath,ll ver,ll l,ll r,ll val)
            {
                if (now==-1||now+1>size)
                {
                    now=size++;
                    fa.push_back(fath),lc.push_back(-1),rc.push_back(-1);
                    if (last!=-1)
                    {
                        sl.push_back(sl[last]),sr.push_back(sr[last]),smid.push_back(smid[last]);
                        sum.push_back(sum[last]),sumlz.push_back(sumlz[last]);
                    }
                    else
                    {
                        sum.push_back(0),sumlz.push_back(0);
                        if (now==rec[ver].rt)
                            sl.push_back(rec[ver].rtl),sr.push_back(rec[ver].rtr);
                        else if (now==lc[fa[now]])
                            sl.push_back(sl[fa[now]]),sr.push_back(smid[fa[now]]);
                        else if (now==rc[fa[now]])
                            sl.push_back(smid[fa[now]]+1),sr.push_back(sr[fa[now]]);
                        smid.push_back((sl[now]+sr[now])>>1);
                    }
                }
                if (last!=-1)
                    sum[now]=sum[last],sumlz[now]=sumlz[last];
                if (sl[now]==l&&r==sr[now])
                {
                    sum[now]+=len(now)*val;
                    sumlz[now]+=val;
                    if (lc[now]==-1&&last!=-1)
                        lc[now]=lc[last];
                    if (rc[now]==-1&&last!=-1)
                        rc[now]=rc[last];
                }
                else
                {
                    if (r<=smid[now])
                        update(lc[now],(last==-1)?-1:lc[last],now,ver,l,r,val);
                    else if (smid[now]+1<=l)
                        update(rc[now],(last==-1)?-1:rc[last],now,ver,l,r,val);
                    else
                    {
                        update(lc[now],(last==-1)?-1:lc[last],now,ver,l,smid[now],val);
                        update(rc[now],(last==-1)?-1:rc[last],now,ver,smid[now]+1,r,val);
                    }
                    if (lc[now]==-1&&last!=-1)
                        lc[now]=lc[last];
                    if (rc[now]==-1&&last!=-1)
                        rc[now]=rc[last];
                    sum[now]=((lc[now]!=-1)?sum[lc[now]]:0)+((rc[now]!=-1)?sum[rc[now]]:0)+len(now)*sumlz[now];
                }
            }
            ll ask(ll now,ll l,ll r,ll sum_lz)
            {
                if (now==-1||now+1>size)
                    return 0;
                if (sl[now]==l&&r==sr[now])
                    return sum[now]+len(now)*sum_lz;
                else
                {
                    if (r<=smid[now])
                        return ask(lc[now],l,r,sum_lz+sumlz[now]);
                    else if (smid[now]+1<=l)
                        return ask(rc[now],l,r,sum_lz+sumlz[now]);
                    else
                        return ask(lc[now],l,smid[now],sum_lz+sumlz[now])+ask(rc[now],smid[now]+1,r,sum_lz+sumlz[now]);
                }
            }
        };
        segtree ltmst;
        
        ll n,m;
        vector<ll> a;
        
        void main()
        {
            while (~scanf("%lld%lld",&n,&m))
            {
                a.resize(n);
                for (ll i=0;i<n;i++)
                    scanf("%lld",&a[i]);
                ltmst.reszcl(1);
                ltmst.set_st(0,0,n-1);
                for (ll i=0;i<n;i++)
                    ltmst.update(ltmst.rec[0].rt,-1,-1,0,i,i,a[i]);
                for (ll i=1,tag=0;i<=m;i++)
                {
                    char o;
                    for (o='$';o!='C'&&o!='Q'&&o!='H'&&o!='B';o=getchar())
                        ;
                    if (o=='C')
                    {
                        if ((++tag)+1>ltmst.rec.size())
                            ltmst.rec.resize(ltmst.rec.size()+1);
                        ltmst.set_st(tag,0,n-1);
                        ll l,r,val;
                        scanf("%lld%lld%lld",&l,&r,&val);
                        ltmst.update(ltmst.rec[tag].rt,ltmst.rec[tag-1].rt,-1,tag,l-1,r-1,val);
                    }
                    else if (o=='Q'||o=='H')
                    {
                        ll l,r,t;
                        scanf("%lld%lld",&l,&r);
                        if (o=='H')
                            scanf("%lld",&t);
                        else
                            t=tag;
                        printf("%lld\n",ltmst.ask(ltmst.rec[t].rt,l-1,r-1,0));
                    }
                    else if (o=='B')
                    {
                        ll t;
                        scanf("%lld",&t);
                        tag=t;
                    }
                }
            }
        }
    }
    
    int main()
    {
        dts::main();
    }
    
  • 1

To the moon(題面原來就是英文,不是我改的)

信息

难度
9
分类
数据结构 | 线段树函数式编程 点击显示
标签
递交数
10
已通过
1
通过率
10%
被复制
1
上传者