zoukankan      html  css  js  c++  java
  • 「模板」 线段树——区间乘 && 区间加 && 区间求和

    「模板」 线段树——区间乘 && 区间加 && 区间求和

    <题目链接>


    来自一个NOIP没学好的省选选手——本应早在NOIP之前学好的内容。

    
    #include <cstdio>
    const int MAXN=100010;
    int n,m;
    long long p;
    class SegmentTree
    {
        public:
            void Build(int i,int l,int r)
            {
                s[i]=node(l,r,1LL,0LL);
                if(l==r)
                {
                    scanf("%lld",&s[i].v);
                    return;
                }
                int j=i<<1,mid=l+r>>1;
                Build(j,l,mid),Build(j|1,mid+1,r);
                PushUp(i);
            }
            void Mul(int i,int l,int r,long long k)
            {
                if(l==s[i].l && r==s[i].r)
                {
                    s[i].v=s[i].v*k%p;
                    s[i].mul=s[i].mul*k%p;
                    s[i].add=s[i].add*k%p;
                    return;
                }
                PushDown(i);
                int j=i<<1,mid=s[i].l+s[i].r>>1;
                if(r<=mid)
                    Mul(j,l,r,k);
                else if(l>mid)
                    Mul(j|1,l,r,k);
                else
                    Mul(j,l,mid,k),Mul(j|1,mid+1,r,k);
                PushUp(i);
            }
            void Add(int i,int l,int r,long long k)
            {
                if(l==s[i].l && r==s[i].r)
                {
                    s[i].v=(s[i].v+(r-l+1)*k)%p;
                    s[i].add=(s[i].add+k)%p;
                    return;
                }
                PushDown(i);
                int j=i<<1,mid=s[i].l+s[i].r>>1;
                if(r<=mid)
                    Add(j,l,r,k);
                else if(l>mid)
                    Add(j|1,l,r,k);
                else
                    Add(j,l,mid,k),Add(j|1,mid+1,r,k);
                PushUp(i);
            }
            long long Sum(int i,int l,int r)
            {
                if(l==s[i].l && r==s[i].r)
                    return s[i].v;
                PushDown(i);
                int j=i<<1,mid=s[i].l+s[i].r>>1;
                if(r<=mid)
                    return Sum(j,l,r);
                else if(l>mid)
                    return Sum(j|1,l,r);
                else
                    return (Sum(j,l,mid)+Sum(j|1,mid+1,r))%p;
            }
        private:
            struct node
            {
                int l,r;
                long long v,mul,add;
                node(int _l=0,int _r=0,long long _mul=0,long long _add=0)
                {
                    l=_l,r=_r,mul=_mul,add=_add;
                }
            }s[MAXN<<2];
            void Update(int i,long long mul,long long add)
            {
                s[i].v=(s[i].v*mul+(s[i].r-s[i].l+1)*add)%p;
                s[i].mul=s[i].mul*mul%p;
                s[i].add=(s[i].add*mul+add)%p;
            }
            void PushUp(int i)
            {
                int j=i<<1;
                s[i].v=(s[j].v+s[j|1].v)%p;
            }
            void PushDown(int i)
            {
                int j=i<<1;
                Update(j,s[i].mul,s[i].add),Update(j|1,s[i].mul,s[i].add);
                s[i].mul=1,s[i].add=0;
            }
    }T;
    int main(int argc,char *argv[])
    {
        scanf("%d %d %lld",&n,&m,&p);
        T.Build(1,1,n);
        for(int i=1,opt,x,y;i<=m;++i)
        {
            long long k;
            scanf("%d %d %d",&opt,&x,&y);
            switch(opt)
            {
                case 1:
                    scanf("%lld",&k);
                    T.Mul(1,x,y,k);
                    break;
                case 2:
                    scanf("%lld",&k);
                    T.Add(1,x,y,k);
                    break;
                case 3:
                    printf("%lld
    ",T.Sum(1,x,y));
                    break;
            }
        }
        return 0;
    }
    

    谢谢阅读。

  • 相关阅读:
    通用数据权限的思考与设计
    MyBatis传入参数为list、数组、map写法
    MyBatis的foreach查询(List、Array、Map)
    heX——基于 HTML5 和 Node.JS 开发桌面应用
    优秀设计:12个带给你灵感的创意单页网站作品
    So Easy!让开发人员更轻松的工具和资源
    触摸手势图标大全:48款触摸手势图标免费下载
    放松的周末,一起欣赏15个华丽的艺术品
    Skytte:一款令人印象深刻的 HTML5 射击游戏
    分享本年度最佳的15个 Photoshop 实例教程
  • 原文地址:https://www.cnblogs.com/Capella/p/8462769.html
Copyright © 2011-2022 走看看