zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    脚本执行策略设置
    获取日期与时间戳小笔记
    Intellij IDEA部分简介
    Intellij IDEA脚本参数化、关联、检查点
    LR中的时间戳
    LeetCode 35.Search Insert Position
    LeetCode 34.Search for a Range
    LeetCode 33.Search in Rotated Sorted Array(M)
    LeetCode 81.Search in Rotated Sorted Array II(M)
    LeetCode 278.First Bad Version(E)(P)
  • 原文地址:https://www.cnblogs.com/LJB666/p/10777963.html
Copyright © 2011-2022 走看看