1551:维护序列(区间乘法+区间加法)

 

虽然感觉是模板题,但做起来很不容易啊

 

 在对区间进行乘法运算 (假设 *k )时,乘法的 lazy 标记需要变为 lazy*k

区间之和 sum 也要变为 sum*k

但是要注意区间的加法运算标记   lazy(add)   也要 *k

因为现有的   lazy(add)   标记还未加到区间中

还应该注意的是

在 lazy 标记的 push_down 操作中,应该先下放   乘法运算的 lazy 标记,因为在上面已经将  lazy(add)   更改了

const int N=1e6+5;
 
    int n,m,t;
    int i,j,k;
    int a[N];
    struct Node
    {
        int l, r;
        ll sum;
        ll fc; // *
        ll fj; // +
        void update_fr(int x)
        {
            sum=sum*x%t;
            fj=fj*x%t;
            fc=fc*x%t;
        }
        void update(int x)
        {
            sum+=1ll*(r-l+1)*x;
            sum%=t;
            fj=(x+fj)%t;
        }
    }node[N<<2];
    
void push_up(int id)
{
    node[id].sum=(node[id<<1].sum+node[id<<1|1].sum)%t;
}

void push_down(int id)
{
    ll x=node[id].fc;
    if(x!=1){
        node[id<<1].update_fr(x);
        node[id<<1|1].update_fr(x);
        node[id].fc=1;
    }
    x=node[id].fj;
    if(x){
        node[id<<1].update(x);
        node[id<<1|1].update(x);
        node[id].fj=0;
    }
}

void build(int l,int r,int id)
{
    node[id].l=l;
    node[id].r=r;
    node[id].fj=0;
    node[id].fc=1;
    if(l==r){
        node[id].sum=a[l]%t;
    } else{
        int mid=l+r>>1;
        build(l,mid,id<<1);
        build(mid+1,r,id<<1|1);
        push_up(id);
    }
}

void update(int l,int r,int x,int id,int kind)
{
    int L=node[id].l;
    int R=node[id].r;
    if(L>=l && r>=R){
        if(kind==1){
            node[id].update_fr(x);
        } else{
            node[id].update(x);
        }
    } else{
        int mid=L+R>>1;
        push_down(id);
        if(mid>=l) update(l,r,x,id<<1,kind);
        if(r>=mid+1) update(l,r,x,id<<1|1,kind);
        push_up(id);
        return ;
    }
}

ll query(int l,int r,int id)
{
    int L=node[id].l;
    int R=node[id].r;
    if(L>=l && r>=R){
        return node[id].sum;
    } else{
        int mid=L+R>>1;
        push_down(id);
        ll ans=0;
        if(mid>=l) ans+=query(l,r,id<<1);
        ans%=t;
        if(r>=mid+1) ans+=query(l,r,id<<1|1);
        ans%=t;
        push_up(id);
        return ans%t;
    }
}

int main()
{
    //IOS;
    while(~sdd(n,t)){
        for(i=1;i<=n;i++) sd(a[i]);
        build(1,n,1);  
        //for(i=2;i<=n;i++) dbg( query(i-1,i,1) );
        sd(m);
        while(m--){
            int l,r,x,tag;
            sd(tag);
            if(tag==3){
                sdd(l,r);
                pll( query(l,r,1)%t );
        //for(i=2;i<=n;i++) dbg( query(i-1,i,1) );
            } else{
                sddd(l,r,x);
                update(l,r,x,1,tag);
        //for(i=2;i<=n;i++) dbg( query(i-1,i,1) );
            }
        }
    }
    //PAUSE;
    return 0;
}

 

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页