洛谷 P2023 维护序列 题解

题面

注意一个细节,查询和更新都需要pushdown();

#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,m,p;
int a[1000010];
struct ha{
    long long v;
    long long mul;
    long long add;
}tree[1000010];
void build(int k,int l,int r)
{
    tree[k].mul=1;
    tree[k].add=0;
    if(l==r){
        tree[k].v=a[l];
    }
    else{
        int mid=(l+r)/2;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
        tree[k].v=tree[k<<1].v+tree[k<<1|1].v;
    }
    tree[k].v%=p;
    return;
}
void pushdown(int k,int l,int r)
{
    int mid=(l+r)/2;
    tree[k<<1].v=(tree[k<<1].v*tree[k].mul+tree[k].add*(mid-l+1))%p;
    tree[k<<1|1].v=(tree[k<<1|1].v*tree[k].mul+tree[k].add*(r-mid))%p;
    tree[k<<1].mul=(tree[k<<1].mul*tree[k].mul)%p;
    tree[k<<1|1].mul=(tree[k<<1|1].mul*tree[k].mul)%p;
    tree[k<<1].add=(tree[k<<1].add*tree[k].mul+tree[k].add)%p;
    tree[k<<1|1].add=(tree[k<<1|1].add*tree[k].mul+tree[k].add)%p;
    tree[k].mul=1;
    tree[k].add=0;
    return;
}
void muladd(int k,int l,int r,int x,int y,int goal)
{
    if(y<l||x>r){
        return;
    }
    if(x<=l&&r<=y){
        tree[k].v=(tree[k].v*goal)%p;
        tree[k].mul=(tree[k].mul*goal)%p;
        tree[k].add=(tree[k].add*goal)%p;
        return;
    }
    pushdown(k,l,r);
    int mid=(l+r)/2;
    muladd(k<<1,l,mid,x,y,goal);
    muladd(k<<1|1,mid+1,r,x,y,goal);
    tree[k].v=(tree[k<<1].v+tree[k<<1|1].v)%p;
    return;
}
void addadd(int k,int l,int r,int x,int y,int goal)
{
    if(x>r||y<l){
        return;
    }
    if(x<=l&&y>=r){
        tree[k].add=(tree[k].add+goal)%p;
        tree[k].v=(tree[k].v+goal*(r-l+1))%p;        
        return;
    }
    pushdown(k,l,r);
    int mid=(l+r)/2;
    addadd(k<<1,l,mid,x,y,goal);
    addadd(k<<1|1,mid+1,r,x,y,goal);
    tree[k].v=(tree[k<<1].v+tree[k<<1|1].v)%p;
    return;
}
int ask(int k,int l,int r,int x,int y)
{
    if(x>r||y<l){
        return 0;
    }
    if(x<=l&&y>=r){
        return tree[k].v;
    }
    pushdown(k,l,r);
    int mid=(l+r)/2;
    return (ask(k<<1,l,mid,x,y)+ask(k<<1|1,mid+1,r,x,y))%p;
}
signed main()
{    
    cin>>n>>p;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    build(1,1,n);
    cin>>m;
    for(int i=1;i<=m;i++){
        int type;
        cin>>type;
        if(type==1){
            int x,y,v;
            cin>>x>>y>>v;
            muladd(1,1,n,x,y,v);
        }
        else if(type==2){
            int x,y,v;
            cin>>x>>y>>v;
            addadd(1,1,n,x,y,v);
        }
        else{
            int x,y;
            cin>>x>>y;
            cout<<ask(1,1,n,x,y)<<endl;
        }
    }
}
原文地址:https://www.cnblogs.com/kamimxr/p/11435443.html