zoukankan      html  css  js  c++  java
  • Evanyou Blog 彩带

      洛谷上的模板,与一般的线段树没什么太大区别,只是区间操作多了一个乘上一个值,用两个标记数组,下推标记的时候记得先乘后加就ok了

      传送门,代码:

    #include<bits/stdc++.h>
    #define ls rt<<1
    #define rs rt<<1|1
    using namespace std;
    
    typedef long long ll;
    const int N=1e5+7;
    int n,m;
    ll seg[N<<2],s1[N<<2],s2[N<<2],a[N],mod;
    
    inline ll read()
    {
        ll x=0; char ch=getchar(); bool flag=false;
        while( ch<'0' || ch>'9' ) {
            if( ch=='-' ) flag=true; ch=getchar();
        }
        while( ch>='0' && ch<='9' ) {
            x=x*10+ch-'0'; ch=getchar();
        }
        return flag ? -x : x;
    }
    
    inline void pushup(int rt)
    {
        seg[rt]=(seg[ls]+seg[rs])%mod;
    }
    
    inline void pushdown(int l,int r,int rt,ll ln,ll rn)
    {
        if( s1[rt]!=1 ) {
            seg[ls]=seg[ls]*s1[rt]%mod;
            seg[rs]=seg[rs]*s1[rt]%mod;
            s1[ls]=s1[ls]*s1[rt]%mod;
            s1[rs]=s1[rs]*s1[rt]%mod;
            s2[ls]=s2[ls]*s1[rt]%mod;
            s2[rs]=s2[rs]*s1[rt]%mod;
            s1[rt]=1;
        }
        if( s2[rt]!=0 ) {
            seg[ls]=(seg[ls]+s2[rt]*ln%mod)%mod;
            seg[rs]=(seg[rs]+s2[rt]*rn%mod)%mod;
            s2[ls]=(s2[ls]+s2[rt])%mod;
            s2[rs]=(s2[rs]+s2[rt])%mod;
            s2[rt]=0;
        }
    }
    
    void build(int l,int r,int rt)
    {    
        s1[rt]=1;
        if( l==r ) { 
            seg[rt]=a[l]%mod; return ;
        }
        int mid=l+r>>1;
        build(l,mid,ls); build(mid+1,r,rs);
        pushup(rt);
    }
    
    void update(int l,int r,int rt,int L,int R,ll C,int type)
    {
        if( L>r || l>R ) return;
        if( L<=l && r<=R ) {
            if( type==1 ) {
                seg[rt]=seg[rt]*C%mod;
                s1[rt]=s1[rt]*C%mod;
                s2[rt]=s2[rt]*C%mod;
            } else {
                seg[rt]=(seg[rt]+C*(r-l+1))%mod;
                s2[rt]=(s2[rt]+C)%mod;
            }
            return;
        }
        int mid=l+r>>1;
        pushdown(l,r,rt,mid-l+1,r-mid);
        if( L<=mid ) update(l,mid,ls,L,R,C,type);
        if( R>mid ) update(mid+1,r,rs,L,R,C,type);
        pushup(rt);
    }
    
    ll query(int l,int r,int rt,int L,int R)
    {
        if( L>r || R<l ) return 0;
        if( L<=l && r<=R ) return seg[rt];
        int mid=l+r>>1; ll ret=0;
        pushdown(l,r,rt,mid-l+1,r-mid);
        if( L<=mid ) ret=(ret+query(l,mid,ls,L,R))%mod;
        if( R>mid ) ret=(ret+query(mid+1,r,rs,L,R))%mod;
        return ret%mod;
    }
    
    int main()
    {
        n=read(); m=read(); mod=read();
        for(int i=1; i<=n; ++i) a[i]=read();
        build(1,n,1);
        int s,x,y; ll z;
        for(int i=1; i<=m; ++i) {
            s=read();
            if( s==1 ) {
                x=read(), y=read(), z=read();
                update(1,n,1,x,y,z,1);
            } else if( s==2 ) {
                x=read(), y=read(), z=read();
                update(1,n,1,x,y,z,2);
            } else {
                x=read(), y=read();
                printf("%lld
    ",query(1,n,1,x,y));
            }
        }
        return 0; 
    }

    貌似又是一道water题。。。

  • 相关阅读:
    2017-2018-2 20179225《网络攻防与实践》 第5周作业
    NetSec2019 20165327 Exp3 免杀原理与实践
    NetSec2019 20165327 Exp2 后门原理与实践
    NetSec2019 20165327 Exp1 PC平台逆向破解
    NetSec2019 20165327 Exp0 Kali安装 Week1
    实验五 通讯协议设计
    2018-2019-1 20165307 20165327 20165332 实验四 外设驱动程序设计
    2018-2019-1 20165327 《信息安全系统设计基础》第八周学习总结
    实现mypwd&mybash&myod&读者写者
    2018-2019-1 20165327 实验三 实时系统
  • 原文地址:https://www.cnblogs.com/cytus/p/7778897.html
Copyright © 2011-2022 走看看