P3373线段树2

Posted lcezych

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",query(1,1,n,l,r)%p);
        
    

 

以上是关于P3373线段树2的主要内容,如果未能解决你的问题,请参考以下文章

P3373 模板线段树 2

P3373线段树2

P3373 模板线段树 2

Luogu P3373 模板线段树 2

线段树 P3373

洛谷P3373 模板线段树 2