zoukankan      html  css  js  c++  java
  • 洛谷P3373线段树模板2

    题目:https://www.luogu.org/problemnew/show/P3373

    带乘的线段树,更新时把加的标记也乘一下,然后取值时先乘后加。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #define ll long long
    using namespace std;
    int const N=100005;
    int n,m,p;
    ll t[N<<2],lc[N<<2],lj[N<<2],a[N<<2];
    void pushup(int x)
    {
        t[x]=(t[x<<1]+t[x<<1|1])%p;
    }
    void pushdown(int l,int r,int x)
    {
        int ls=(x<<1),rs=(x<<1|1);
        int mid=(l+r)/2;
        
        t[ls]*=lc[x];t[ls]+=lj[x]*(mid-l+1);//!
        t[rs]*=lc[x];t[rs]+=lj[x]*(r-mid);//!
        
        lj[ls]*=lc[x];lj[ls]+=lj[x];
        lj[rs]*=lc[x];lj[rs]+=lj[x];
        lc[ls]*=lc[x];lc[rs]*=lc[x];
        lj[x]=0;lc[x]=1;
        
        t[ls]%=p;t[rs]%=p;
        lj[ls]%=p;lj[rs]%=p;
        lc[ls]%=p;lc[rs]%=p;
    }
    void build(int l,int r,int x)
    {
        lc[x]=1;lj[x]=0;
        if(l==r)
        {
            t[x]=a[l];
            return;
        }
        int mid=(l+r)/2;
        build(l,mid,x<<1);
        build(mid+1,r,x<<1|1);
        pushup(x);
    }
    void update(int l,int r,int L,int R,int s,int tp,int x)
    {
        if(tp==1)//c
        {
            if(l>=L&&r<=R)
            {
                lj[x]=(lj[x]*s)%p;
                lc[x]=(lc[x]*s)%p;
                t[x]=(t[x]*s)%p;
                return;
            }
            pushdown(l,r,x);
            int mid=(l+r)/2;
            if(mid>=L)update(l,mid,L,R,s,tp,x<<1);
            if(mid<R)update(mid+1,r,L,R,s,tp,x<<1|1);
            pushup(x);
        }
        if(tp==2)//j
        {
            if(l>=L&&r<=R)
            {
                lj[x]=(lj[x]+s)%p;
                t[x]=(t[x]+s*(r-l+1))%p;//!
                return;
            }
            pushdown(l,r,x);
            int mid=(l+r)/2;
            if(mid>=L)update(l,mid,L,R,s,tp,x<<1);
            if(mid<R)update(mid+1,r,L,R,s,tp,x<<1|1);
            pushup(x);
        }
    }
    ll query(int l,int r,int L,int R,int x)
    {
        if(l>=L&&r<=R)return t[x];
        pushdown(l,r,x);
        int mid=(l+r)/2,ans=0;
        if(mid>=L)ans=(ans+query(l,mid,L,R,x<<1))%p;
        if(mid<R)ans=(ans+query(mid+1,r,L,R,x<<1|1))%p;
        return ans;
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&p);
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]);
        build(1,n,1);
        while(m--)
        {
            int x,y,k,j;
            scanf("%d",&j);
            if(j==1)
            {
                scanf("%d%d%d",&x,&y,&k);
                update(1,n,x,y,k,1,1);
            }
            if(j==2)
            {
                scanf("%d%d%d",&x,&y,&k);
                update(1,n,x,y,k,2,1);
            }
            if(j==3)
            {
                scanf("%d%d",&x,&y);
                printf("%lld
    ",query(1,n,x,y,1)%p);
            }
        }
        return 0;
    }
  • 相关阅读:
    python用户交互
    python注释
    python变量
    命令行模式和python交互模式
    python解释器
    利用excel生成word,批量插入图片、题注、标题等格式
    520了,用32做个简单的小程序
    利用excel生成word,批量插入图片、题注、标题等格式
    数据结构与算法
    MySQL8.0-INFORMATION_SCHEMA增强
  • 原文地址:https://www.cnblogs.com/Zinn/p/8723441.html
Copyright © 2011-2022 走看看