P2023 [AHOI2009]维护序列 区间加乘模板

题意:

有长为N的数列,不妨设为a1,a2,…,aN 。有如下三种操作形式:N<=1e5
(1)把数列中的一段数全部乘一个值;
(2)把数列中的一段数全部加一个值;
(3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值。

思路:

线段树,因为有可能存在,同时加和乘,所以lazy标记变为二维,一个记录乘,一个记录加

因为乘是总和乘一个数,所以先乘再加,这里需要注意,因为原本的区间和可能是zhi+lazy【加】,乘是总体,所以标记lazy【加】也要乘

 il void pushdown(int x,ll mod,int l,int r){
     if(lazy[x][1]!=1){
         tree[x<<1]*=lazy[x][1];tree[x<<1]%=mod;
         tree[x<<1|1]*=lazy[x][1];tree[x<<1|1]%=mod;
         lazy[x<<1][1]*=lazy[x][1];lazy[x<<1][1]%=mod;
         lazy[x<<1|1][1]*=lazy[x][1];lazy[x<<1|1][1]%=mod;
         lazy[x<<1][0]*=lazy[x][1];lazy[x<<1][0]%=mod;
         lazy[x<<1|1][0]*=lazy[x][1];lazy[x<<1|1][0]%=mod;
         lazy[x][1]=1;
    }
     if(lazy[x][0]!=0){
         int mid=(l+r)>>1;
         tree[x<<1]+=(mid-l+1)*lazy[x][0];tree[x<<1]%=mod;
         tree[x<<1|1]+=(r-mid)*lazy[x][0];tree[x<<1|1]%=mod;
         lazy[x<<1][0]+=lazy[x][0];lazy[x<<1][0]%=mod;
         lazy[x<<1|1][0]+=lazy[x][0];lazy[x<<1|1][0]%=mod;
         lazy[x][0]=0;
     }
 }

 

这题也wa了好多遍,直到最后相通了,当加和乘同时存在的时候

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define il inline
#define it register int
#define inf 0x3f3f3f3f
#define lowbit(x) (x)&(-x)
#define mem(a,b) memset(a,b,sizeof(a))
#define modd 998244353
const int maxn=2e5+10;
int n,m,k;
ll p;
ll tree[maxn<<2],lazy[maxn<<2][2],a[maxn];
il void pushdown(int x,ll mod,int l,int r){
    if(lazy[x][1]!=1){
        tree[x<<1]*=lazy[x][1];tree[x<<1]%=mod;
        tree[x<<1|1]*=lazy[x][1];tree[x<<1|1]%=mod;
        lazy[x<<1][1]*=lazy[x][1];lazy[x<<1][1]%=mod;
        lazy[x<<1|1][1]*=lazy[x][1];lazy[x<<1|1][1]%=mod;
        lazy[x<<1][0]*=lazy[x][1];lazy[x<<1][0]%=mod;
        lazy[x<<1|1][0]*=lazy[x][1];lazy[x<<1|1][0]%=mod;
        lazy[x][1]=1;
    }
    if(lazy[x][0]!=0){
        int mid=(l+r)>>1;
        tree[x<<1]+=(mid-l+1)*lazy[x][0];tree[x<<1]%=mod;
        tree[x<<1|1]+=(r-mid)*lazy[x][0];tree[x<<1|1]%=mod;
        lazy[x<<1][0]+=lazy[x][0];lazy[x<<1][0]%=mod;
        lazy[x<<1|1][0]+=lazy[x][0];lazy[x<<1|1][0]%=mod;
        lazy[x][0]=0;
    }
}
il void pushup(int x,ll mod){
    tree[x]=(tree[x<<1]+tree[x<<1|1])%mod;
}
void build(int x,int l,int r,ll mod){
    lazy[x][1]=1;lazy[x][0]=0;
    if(l==r){
        tree[x]=a[l];return;
    }
    int mid=(l+r)>>1;
    build(x<<1,l,mid,mod);
    build(x<<1|1,mid+1,r,mod);
    pushup(x,mod);
}
void updatej(int x,int l,int r,int l1,int r1,ll zhi,ll mod){
    if(l1<=l && r<=r1){
        pushdown(x,mod,l,r);
        lazy[x][0]=zhi;tree[x]+=(ll)(r-l+1)*zhi;tree[x]%=mod;
        return;
    }
    pushdown(x,mod,l,r);
    int mid=(l+r)>>1;
    if(l1<=mid){
        updatej(x<<1,l,mid,l1,r1,zhi,mod);
    }
    if(r1>mid){
        updatej(x<<1|1,mid+1,r,l1,r1,zhi,mod);
    }
    pushup(x,mod);
}
void updatec(int x,int l,int r,int l1,int r1,ll zhi,ll mod){
    if(l1<=l && r<=r1){
        pushdown(x,mod,l,r);
        lazy[x][1]=zhi;tree[x]*=zhi;tree[x]%=mod;
        return;
    }
    pushdown(x,mod,l,r);
    int mid=(l+r)>>1;
    if(l1<=mid){
        updatec(x<<1,l,mid,l1,r1,zhi,mod);
    }
    if(r1>mid){
        updatec(x<<1|1,mid+1,r,l1,r1,zhi,mod);
    }
    pushup(x,mod);
}
ll query(int x,int l,int r,int l1,int r1,ll mod){
    if(l1<=l && r<=r1){
       return tree[x];
    }
    pushdown(x,mod,l,r);
    int mid=(l+r)>>1;
    ll sum=0;
    if(l1<=mid){
        sum+=query(x<<1,l,mid,l1,r1,mod);sum%=mod;
    }
    if(r1>mid){
        sum+=query(x<<1|1,mid+1,r,l1,r1,mod);sum%mod;
    }
    return sum%mod;
}
int main(){
    scanf("%d%lld",&n,&p);
    for(it i=1;i<=n;i++){
        scanf("%lld",&a[i]);a[i]%=p;
    }
    build(1,1,n,p);

    scanf("%d",&m);
    while(m--){//cout<<tree[1]<<endl;
        int t,g;
        ll c;
        scanf("%d",&k);
        if(k==1){
            scanf("%d%d%lld",&t,&g,&c);
            updatec(1,1,n,t,g,c%p,p);
        }
        else if(k==2){
            scanf("%d%d%lld",&t,&g,&c);
            updatej(1,1,n,t,g,c%p,p);
        }
        else{
            scanf("%d%d",&t,&g);
            printf("%lld\n",query(1,1,n,t,g,p));
        }
    }
    return 0;
}

 

posted @ 2020-02-19 19:15  ouluy  阅读(158)  评论(0)    收藏  举报