• P3373线段树2


    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const ll N=100001;
    ll sum[N<<2],lazy1[N<<2],lazy2[N<<2];
    ll a[N];
    ll n,m,p;
    
    inline ll read()
    {
        ll ans=0;
        char last=' ',ch=getchar();
        while(ch<'0'||ch>'9') last=ch,ch=getchar();
        while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
        if(last=='-') ans=-ans;
        return ans;
    }
    
    void build(ll cnt,ll l,ll r)
    {
        if(l==r) 
        {
            sum[cnt]=a[l]%p;
            return;
        }
        else 
        {
            ll mid=(l+r)>>1;
            build(cnt<<1,l,mid);
            build((cnt<<1)|1,mid+1,r);
            sum[cnt]=(sum[cnt<<1]+sum[(cnt<<1)|1])%p;
        }
    }
    
    inline bool cover(ll nl,ll nr,ll l,ll r)
    {
        return l<=nl&&r>=nr;
    }
    
    inline bool intersection(ll nl,ll nr,ll l,ll r)
    {
        return l<=nr&&r>=nl;
    }
    
    void pushdown(ll cnt,ll l,ll r)
    {
        ll mid=(l+r)>>1;
        lazy1[cnt<<1]=(lazy1[cnt<<1]*lazy2[cnt]+lazy1[cnt])%p;
        lazy1[(cnt<<1)|1]=(lazy1[(cnt<<1)|1]*lazy2[cnt]+lazy1[cnt])%p;
        lazy2[cnt<<1]=(lazy2[cnt<<1]*lazy2[cnt]%p)%p;
        lazy2[(cnt<<1)|1]=(lazy2[(cnt<<1)|1]*lazy2[cnt]%p)%p;
        sum[cnt<<1]=((lazy1[cnt]*(mid-l+1)%p)+(sum[cnt<<1]*lazy2[cnt]%p))%p;
        sum[cnt<<1|1]=((lazy1[cnt]*(r-mid)%p)+(sum[cnt<<1|1]*lazy2[cnt]%p))%p;
        lazy2[cnt]=1;
        lazy1[cnt]=0;
    }
    
    void add1(ll cnt,ll nl,ll nr,ll l,ll r,ll a)
    {
        if(cover(nl,nr,l,r))
        {
            sum[cnt]=(sum[cnt]+(nr-nl+1)*a%p)%p;
            lazy1[cnt]=(lazy1[cnt]+a%p)%p;
            return ;
        }
        pushdown(cnt,nl,nr);
        ll mid=(nl+nr)>>1;
        if(intersection(nl,mid,l,r)) add1(cnt<<1,nl,mid,l,r,a);
        if(intersection(mid+1,nr,l,r)) add1(cnt<<1|1,mid+1,nr,l,r,a);
        sum[cnt]=(sum[cnt<<1]+sum[cnt<<1|1])%p;
    }
    
    void add2(ll cnt,ll nl,ll nr,ll l,ll r,ll a)
    {
        if(cover(nl,nr,l,r))
        {
            sum[cnt]=(sum[cnt]*a)%p;
            lazy1[cnt]=(lazy1[cnt]*a)%p;
            lazy2[cnt]=(lazy2[cnt]*a)%p;
            return ;
        }
        pushdown(cnt,nl,nr);
        ll mid=(nl+nr)>>1;
        if(intersection(nl,mid,l,r)) add2(cnt<<1,nl,mid,l,r,a);
        if(intersection(mid+1,nr,l,r)) add2(cnt<<1|1,mid+1,nr,l,r,a);
        sum[cnt]=(sum[cnt<<1]+sum[cnt<<1|1])%p;
    }
    
    ll query(ll cnt,ll nl,ll nr,ll l,ll r)
    {
        if(cover(nl,nr,l,r))
        {
            return sum[cnt]%p;
        }
        pushdown(cnt,nl,nr);
        ll mid=(nl+nr)>>1;
        ll ans=0;
        if(intersection(nl,mid,l,r)) ans+=query(cnt<<1,nl,mid,l,r)%p;
        if(intersection(mid+1,nr,l,r)) ans+=query(cnt<<1|1,mid+1,nr,l,r)%p;
        return ans;
    }
    
    
    int main()
    {
        n=read(),m=read(),p=read();
        for(ll i=1;i<=n;i++)
            a[i]=read();
        for(int i=1;i<=N<<2;i++) lazy2[i]=1;
        build(1,1,n);
        while(m--)
        {
            ll k;
            k=read();
            if(k==1)
            {
                ll l=read(),r=read(),t=read();
                add2(1,1,n,l,r,t);
            }
            if(k==2)
            {
                ll l=read(),r=read(),t=read();
                add1(1,1,n,l,r,t);
            }
            if(k==3)
            {
                ll l=read(),r=read();
                printf("%lld
    ",query(1,1,n,l,r)%p);
            }
        }
    }
  • 相关阅读:
    Linux中的文件特殊权限
    服务器管理
    程序图表统计知识
    EasyUI 添加tab页(iframe方式)
    打造自己的reset.css
    CI的知识点
    easyui资源
    eval解析JSON中的注意点
    如何在一个frame中调用另一个frame中的javascript函数
    Egret 摇一摇功能
  • 原文地址:https://www.cnblogs.com/lcezych/p/11116318.html
Copyright © 2020-2023  润新知