• 【模板】线段树 2


     【模板】线段树 2

    乘法懒标等于0也要下传,每次乘法操作对加法也要进行

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    const int maxn=1e5+10;
    int v[maxn*4],L[maxn*4],R[maxn*4],lazy1[maxn*4],lazy2[maxn*4];
    int A[maxn];
    int mod;
    void build(int l,int r,int x)
    {
        L[x]=l,R[x]=r;
        lazy1[x]=1,lazy2[x]=0;
        //v[x]=0;
        if(l==r)
        {
            v[x]=(A[l])%mod;
            return ;
        }
        int mid=(l+r)/2;
        build(l,mid,x*2);
        build(mid+1,r,x*2+1);
        v[x]=(v[2*x]+v[2*x+1])%mod;
    }
    void pushdown(int x)
    {
       // if(lazy1[x]): lazy1[x]==0
        {
            v[x*2]=(v[x*2]*lazy1[x])%mod;
            v[x*2+1]=(v[x*2+1]*lazy1[x])%mod;
            lazy1[x*2]=(lazy1[x]*lazy1[x*2])%mod;
            lazy1[x*2+1]=(lazy1[x]*lazy1[x*2+1])%mod;
            lazy2[x*2]=(lazy1[x]*lazy2[x*2])%mod;
            lazy2[x*2+1]=(lazy1[x]*lazy2[x*2+1])%mod;
            lazy1[x]=1;
         if(lazy2[x]){
            v[2*x]=(v[2*x]+lazy2[x]*(R[2*x]-L[2*x]+1)%mod)%mod;
            v[2*x+1]=(v[2*x+1]+lazy2[x]*(R[2*x+1]-L[2*x+1]+1)%mod)%mod;
            lazy2[x*2]=(lazy2[x]+lazy2[x*2])%mod;
            lazy2[x*2+1]=(lazy2[x]+lazy2[x*2+1])%mod;
            lazy2[x]=0;}
    
        }
    }
    void update1(int l,int r,int x,int t)
    {
        if(l<=L[x]&&R[x]<=r)
        {
            v[x]=(v[x]+t*(R[x]-L[x]+1)%mod)%mod;
            lazy2[x]=(lazy2[x]+t)%mod;
            return ;
        }
        pushdown(x);
        int mid=(L[x]+R[x])/2;
        if(l<=mid)update1(l,r,x*2,t);
        if(r>mid)update1(l,r,x*2+1,t);
        v[x]=(v[2*x]+v[2*x+1])%mod;
    }
    void update2(int l,int r,int x,int t)
    {
        if(l<=L[x]&&R[x]<=r)
        {
            v[x]=(v[x]*t)%mod;
            lazy2[x]=(lazy2[x]*t)%mod;
            lazy1[x]=(lazy1[x]*t)%mod;
            return ;
        }
        pushdown(x);
        int mid=(L[x]+R[x])/2;
        if(l<=mid)update2(l,r,x*2,t);
        if(r>mid)update2(l,r,x*2+1,t);
        v[x]=(v[2*x]+v[2*x+1])%mod;
    }
    
    
    int query(int l,int r,int x)
    {
    
        if(l<=L[x]&&R[x]<=r)
        {
           // cout<<v[x]<<"QUE"<<endl;
            return v[x]%mod;
        }
        int mid=(L[x]+R[x])/2;
        int ans=0;
        pushdown(x);
        if(l<=mid)
            ans+=query(l,r,x*2)%mod;
        if(r>mid) ans=(ans+query(l,r,x*2+1))%mod;
        return ans%mod;
    }
    signed main()
    {
        int n,m;
        int x,y,z,k;
        //while(
        //freopen("a.txt","w",stdout);
        scanf("%lld%lld%lld",&n,&m,&mod);
        {
            for(int i=1; i<=n; i++)
            {
                scanf("%lld",&A[i]);
            }
            build(1,n,1);
            while(m--)
            {
               
                scanf("%lld",&x);
                if(x==2)
                {
                    scanf("%lld%lld%lld",&y,&z,&k);
                    update1(y,z,1,k);
                }
                else if(x==1)
                {
                    scanf("%lld%lld%lld",&y,&z,&k);
                    update2(y,z,1,k);
                }
                else
                {
                    scanf("%lld%lld",&y,&z);
    
                    cout<<query(y,z,1)<<'
    ';
                }
            }
        }
    
    
    
    }
  • 相关阅读:
    vue项目实践-添加axios封装api请求
    travis-ci 中运行 puppeteer
    ubuntu 16.04 TLS 安装VNC
    duilib bkimage 属性
    Android后台服务拍照
    mongodb 设置用户密码权限
    App爬虫神器mitmproxy和mitmdump的使用
    insserv: Script <name> is broken: incomplete LSB comment.
    ubuntu ssh root登陆
    virtualbox 迁移虚拟机存储位置
  • 原文地址:https://www.cnblogs.com/liulex/p/11432987.html
Copyright © 2020-2023  润新知