• 线段树(标记下传乘法和加法)


    传送门:https://www.luogu.org/problem/P3373

    标记下传,这种东西就是在求和和更改的时候进行pushdown把标记(各种标记,类似于寒冰标记、痛苦标记、穹妹标记……)下传,来节省时间。

    还是挺简单的,主要问题处在pushdown上但多看看就会了

    #include<bits/stdc++.h>
    using namespace std;
    long long n,m,p;
    long long multag[1000009];
    long long addtag[1000009];
    long long seg[4000009];
    long long num[1000009];
    inline long long kd()
    {
        long long x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+(ch^48);ch=getchar();}
        return x*f;
    }
    inline long long ls(long long x){return x<<1;}
    inline long long rs(long long x){return x<<1|1;}
    void build(long long now,long long l,long long r)
    {
        addtag[now]=0;
        multag[now]=1;
        if(l==r)
        {
            seg[now]=num[l]%p;
            return;
        }
        long long mid=(l+r)>>1;
        build(ls(now),l,mid);
        build(rs(now),mid+1,r);
        seg[now]=(seg[ls(now)]+seg[rs(now)])%p;
        return;
    }
    void pushdown(long long now,long long l,long long r)
    {
        long long mid=(l+r)>>1;
        seg[ls(now)]=(seg[ls(now)]*multag[now]+addtag[now]*(mid-l+1))%p;
        seg[rs(now)]=(seg[rs(now)]*multag[now]+addtag[now]*(r-mid))%p;
        multag[ls(now)]=(multag[ls(now)]*multag[now])%p;
        multag[rs(now)]=(multag[rs(now)]*multag[now])%p;
        addtag[ls(now)]=(addtag[ls(now)]*multag[now]+addtag[now])%p;
        addtag[rs(now)]=(addtag[rs(now)]*multag[now]+addtag[now])%p;
        multag[now]=1;
        addtag[now]=0;
    }
    void mulchange(long long now,long long l,long long r,long long a,long long b,long long c)
    {
        if(r<a||l>b)return;
    
        if(a<=l&&r<=b)
        {
            seg[now]=(seg[now]*c)%p;
            multag[now]=(multag[now]*c)%p;
            addtag[now]=(addtag[now]*c)%p;
            return;
        }
        pushdown(now,l,r);
        long long mid=(l+r)>>1;
        mulchange(ls(now),l,mid,a,b,c);
        mulchange(rs(now),mid+1,r,a,b,c);
        seg[now]=(seg[ls(now)]+seg[rs(now)])%p;
        return;
    }
    void addchange(long long now,long long l,long long r,long long a,long long b,long long c)
    {    
        if(r<a||l>b)return;
        if(l>=a&&r<=b)
        {
            addtag[now]=(addtag[now]+c)%p;
            seg[now]=(seg[now]+c*(r-l+1))%p;
            return;
        }
        pushdown(now,l,r);
        long long mid=(l+r)>>1;
        addchange(ls(now),l,mid,a,b,c);
        addchange(rs(now),mid+1,r,a,b,c);
        seg[now]=(seg[ls(now)]+seg[rs(now)])%p;
        return;
    }
    long long query(long long now,long long l,long long r,long long a,long long b)
    {
        if(r<a||l>b)return 0;
        if(l>=a&&r<=b)return seg[now];
        pushdown(now,l,r);
        long long mid=(l+r)>>1;
        return (query(ls(now),l,mid,a,b)+query(rs(now),mid+1,r,a,b))%p;
    }
    int main()
    {
        n=kd(),m=kd(),p=kd();
        for(register int i=1;i<=n;i++)
        {
            num[i]=kd();
        }
        build(1,1,n);
        for(int i=1;i<=m;i++)
        {
            long long pan=kd();
            long long a=kd(),b=kd();
            if(pan==1)
            {
                long long c=kd();
                mulchange(1,1,n,a,b,c);
            }
            if(pan==2)
            {
                long long c=kd();
                addchange(1,1,n,a,b,c);
            }
            if(pan==3)
            {
                cout<<query(1,1,n,a,b)<<endl;
            }
        }
        return 0;
    }
  • 相关阅读:
    【折腾】Docker官网下载Docker实在太慢怎么破!!!!!windows 安装docker
    centos7搭建FTP文件服务器--虚拟用户
    AWK简单案例
    SaltStack系统初始化
    ReactNative环境搭配及软件安装
    extundelete工具恢复误删文件
    linux磁盘阵列raid1的搭建教程
    linux中Raid0磁盘阵列的搭建
    子网掩码的计算方法
    linux网络管理命令
  • 原文地址:https://www.cnblogs.com/1129-tangqiyuan/p/11754203.html
Copyright © 2020-2023  润新知