zoukankan      html  css  js  c++  java
  • 洛谷 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;
            }
        }
    }
  • 相关阅读:
    NFramework开源AOP框架设计文档
    gdi+学习笔记(1)
    winform 二进制图片处理
    电脑屏幕分辨率多少合适
    c# winform AutoScaleMode属性 转
    Windows server 2008,Windows server 2008 R2,Windows 2008 SP2 区别
    视频分辨率
    ref和out(MSDN)
    转DirectX、Directshow介绍
    shell 命令的使用
  • 原文地址:https://www.cnblogs.com/kamimxr/p/11435443.html
Copyright © 2011-2022 走看看