zoukankan      html  css  js  c++  java
  • [线段树]Luogu P3373 【模板】线段树 2

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define R register
    #define llt long long int
    #define N 100000
    using namespace std;
    inline void read(llt& x){
        char temp=getchar();bool u=0;
        for(x=0;temp<'0'||temp>'9';u=temp=='-',temp=getchar());
        for(;temp>='0'&&temp<='9';x=x*10+temp-'0',temp=getchar());
        if(u)x=-x;
        return ;
    }
    llt n,m,p;
    llt A[N];
    llt val[N<<2];
    llt add[N<<2];
    llt mul[N<<2];
    inline llt add_(R llt x,R llt y){
        return (x+y)%p;
    }
    inline llt mul_(R llt x,R llt y){
        return (x*y)%p;
    }
    void init(llt k=1,llt l=1,llt r=n){
        add[k]=0;
        mul[k]=1;
        if(l==r){
            val[k]=A[l]%p;
            return ;
        }
        R llt mid=(l+r)>>1;
        init(k<<1,l,mid);
        init(k<<1|1,mid+1,r);
        val[k]=add_(val[k<<1],val[k<<1|1]);
        return ;
    }
    void pushdown(llt &k,llt &l,llt &r,llt &mid){
        R llt ls=k<<1,rs=k<<1|1;
        val[ls]=mul_(val[ls],mul[k]);
        val[rs]=mul_(val[rs],mul[k]);
        val[ls]=add_(val[ls],add[k]*(mid-l+1));
        val[rs]=add_(val[rs],add[k]*(r-mid));
        mul[ls]=mul_(mul[ls],mul[k]);
        mul[rs]=mul_(mul[rs],mul[k]);
        add[ls]=mul_(add[ls],mul[k]);
        add[rs]=mul_(add[rs],mul[k]);
        add[ls]=add_(add[ls],add[k]);
        add[rs]=add_(add[rs],add[k]);
        add[k]=0;
        mul[k]=1;
        return ;
    }
    void ch1(llt &x,llt &y,llt &v,llt k=1,llt l=1,llt r=n){
        if(l>=x&&y>=r){
            mul[k]=mul_(mul[k],v);
            add[k]=mul_(add[k],v);
            val[k]=mul_(val[k],v);
            return ;
        }
        R llt mid=(l+r)>>1;
        pushdown(k,l,r,mid);
        if(x<=mid)ch1(x,y,v,k<<1,l,mid);
        if(mid<y)ch1(x,y,v,k<<1|1,mid+1,r);
        val[k]=add_(val[k<<1],val[k<<1|1]);
        return ;
    }
    void ch2(llt &x,llt &y,llt &v,llt k=1,llt l=1,llt r=n){
        if(l>=x&&y>=r){
            add[k]=add_(add[k],v);
            val[k]=add_(val[k],mul_(v,r-l+1));
            return ;
        }
        R llt mid=(l+r)>>1;
        pushdown(k,l,r,mid);
        if(x<=mid)ch2(x,y,v,k<<1,l,mid);
        if(mid<y)ch2(x,y,v,k<<1|1,mid+1,r);
        val[k]=add_(val[k<<1],val[k<<1|1]);
        return ;
    }
    llt get(llt &x,llt &y,llt k=1,llt l=1,llt r=n){
        if(l>=x&&y>=r)return val[k];
        R llt mid=(l+r)>>1;
        R llt res=0;
        pushdown(k,l,r,mid);
        if(x<=mid)res=add_(res,get(x,y,k<<1,l,mid));
        if(mid<y)res=add_(res,get(x,y,k<<1|1,mid+1,r));
        return res%p;
    }
    int main(){
        R llt i,tmp,x,y;
        read(n);
        read(m);
        read(p);
        for(i=1;i<=n;i++)
            read(A[i]);
        init();
        for(i=1;i<=m;i++){
            read(tmp);
            read(x);
            read(y);
            switch(tmp){
                case 1:{
                    read(tmp);
                    ch1(x,y,tmp);
                    break;
                }
                case 2:{
                    read(tmp);
                    ch2(x,y,tmp);
                    break;
                }
                case 3:{
                    printf("%lld
    ",get(x,y));
                    break;
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    最长公共子序列
    学习MySQL常用操作命令
    using的几种用法
    C++循环的简单使用【闲来写来练练手~】
    使用【数据库收缩功能】实现多个数据文件的合并
    Google的十个核心技术(摘自CSDN)
    OPENGL入门学习
    dive into python 第 5 章 对象和面向对象
    [转]已知两圆圆心坐标及半径求两圆交点 (C语言|参数方程求解)
    The Python Tutorial 4. More Control Flow Tools的一些小记
  • 原文地址:https://www.cnblogs.com/TbIblog/p/11208343.html
Copyright © 2011-2022 走看看