• P2023 [AHOI2009]维护序列


    震惊,双倍经验,依旧是线段树的乘法修改

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1000010;
    struct sege_tree
    {
        int l;
        int r;
        long long lazymul;
        long long lazyadd;
        long long v;
    }tree[7*maxn];
    int a[maxn];
    long long p,ans;
    int n,m,opt,l,r;
    long long t;
    void build(int now,int l,int r)
    {
        tree[now].l=l;
        tree[now].r=r;
        tree[now].lazymul=1;
        tree[now].lazyadd=0;
        if(l==r)
        {
            tree[now].v=a[l];
            return;
        }
        else
        {
            int mid=(l+r)>>1;
            build(now*2,l,mid);
            build(now*2+1,mid+1,r);
            tree[now].v=tree[now*2].v+tree[now*2+1].v;
        }    
        tree[now].v%=p;
        return;
    }
    void pushdown(int now,int l,int r)//标记下传 
    {
        int mid=(l+r)>>1;
        tree[now*2].v=(tree[now*2].v*tree[now].lazymul+tree[now].lazyadd*(mid-l+1))%p;
        tree[now*2+1].v=(tree[now*2+1].v*tree[now].lazymul+tree[now].lazyadd*(r-mid))%p;
        tree[now*2].lazymul=(tree[now*2].lazymul*tree[now].lazymul)%p;
        tree[now*2+1].lazymul=(tree[now*2+1].lazymul*tree[now].lazymul)%p;
        tree[now*2].lazyadd=(tree[now*2].lazyadd*tree[now].lazymul+tree[now].lazyadd)%p;
        tree[now*2+1].lazyadd=(tree[now*2+1].lazyadd*tree[now].lazymul+tree[now].lazyadd)%p;
        tree[now].lazymul=1;
        tree[now].lazyadd=0;
        return;
    }
    void update1(int now,int stdl,int stdr,int l,int r,long long k)
    {
        if(l>stdr||r<stdl)
        {
            return;
        }
        if(l<=stdl&&r>=stdr)
        {
            tree[now].v=(tree[now].v*k)%p;
            tree[now].lazymul=(tree[now].lazymul*k)%p;
            tree[now].lazyadd=(tree[now].lazyadd*k)%p;
            return;
        }
        pushdown(now,stdl,stdr);
        int mid=(stdl+stdr)>>1;
        update1(now*2,stdl,mid,l,r,k);
        update1(now*2+1,mid+1,stdr,l,r,k);
        tree[now].v=(tree[now*2].v+tree[now*2+1].v)%p;
        return;
    }
    void update2(int now,int stdl,int stdr,int l,int r,long long k)
    {
        if(l>stdr||r<stdl)
        {
            return;
        }
        if(l<=stdl&&r>=stdr)
        {
            tree[now].lazyadd=(tree[now].lazyadd+k)%p;
            tree[now].v=(tree[now].v+k*(stdr-stdl+1))%p;
            return;
        }
        pushdown(now,stdl,stdr);
        int mid=(stdl+stdr)>>1;
        update2(now*2,stdl,mid,l,r,k);
        update2(now*2+1,mid+1,stdr,l,r,k);
        tree[now].v=(tree[now*2].v+tree[now*2+1].v)%p;
    }
    long long query(int now,int stdl,int stdr,int l,int r)
    {
        if(stdl>r||stdr<l)
        {
            return 0;
        }
        if(stdl>=l&&stdr<=r)
        {
            return tree[now].v;
        }
        pushdown(now,stdl,stdr);
        int mid=(stdl+stdr)>>1;
        return (query(now*2,stdl,mid,l,r)+query(now*2+1,mid+1,stdr,l,r))%p;
    }
    int main()
    {
        cin>>n>>p;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        build(1,1,n);
        cin>>m;
        while(m--)
        {
            scanf("%d",&opt);
            if(opt==1)
            {
                cin>>l>>r>>t;
                update1(1,1,n,l,r,t);
            }
            else if(opt==2)
            {
                cin>>l>>r>>t;
                update2(1,1,n,l,r,t);
            }
            else
            {
                cin>>l>>r;
                cout<<query(1,1,n,l,r)<<endl;
            }
        }
        return 0;
    }
  • 相关阅读:
    NOIP 2008 立体图
    JDOJ 1606 数字三角形
    JDOJ 1133 分段公司利润
    NOIP 2011 选择客栈
    NOIP 2014 无线网络发射器选址
    USACO Party Invitations
    NOI 2001 食物链
    NOI 2002 银河英雄传说
    BOI 2003 团伙
    NOIP 2017 奶酪
  • 原文地址:https://www.cnblogs.com/LJB666/p/10777963.html
Copyright © 2020-2023  润新知