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;
    }
  • 相关阅读:
    大伯的八十岁寿辰
    收到 wincore.cpp 中一个 " ASSERT " BUG: 当 MFC 应用程序 Visual C++ 中 MFC 规则 DLL 中调用函数声明
    命名空间Microsoft.Office.Interop.Word不存在....
    中国测绘科学研究院招聘WEBGIS开发工程师与客座研究生
    开源GIS学习笔记 sinoly BLOGJAVA
    2007年7月9日星期一
    转载:使用感受: VC2005 VC6.0
    推荐:用ogr和PIL把矢量数据转化成栅格图像
    《赢在中国》感言
    VS2005的断点无效问题
  • 原文地址:https://www.cnblogs.com/LJB666/p/10777963.html
Copyright © 2011-2022 走看看