zoukankan      html  css  js  c++  java
  • 线段树2(P3373)

    传送

    感谢洛谷题解让我理清了这一撮标记

    这里多了一个乘法操作,乘法的优先级高于加法。我们来思考一下有关标记的问题。

    首先由两种操作,可以想到要有两个标记,一个标记乘法(mul[k]),一个标记加法(add[k])。

    如果这一步是加法,就直接在原来的add上面增加即可(加法不会对mul产生影响)(这里的“原来的add”是指已经处理好加法,乘法关系的add),sum也按照线段树1的方式维护。

    如果这一步是乘法,因为乘法的优先级高于加法,所以乘法会对当前的add产生影响,即add[k]要乘当前的数。mul[k],sum[k]直接乘当前的数即可。

    再考虑一下标记下传。

    子节点收到父亲节点的add和mul之后,我们就要考虑是先用父亲的add还是mul去更新子节点(即先乘再加还是先加再乘)。我们上面处理add的时候,就已经考虑到了mul对add的影响,如果这时候先加再乘,就会造成翻倍的错误,所以我们先乘再加(也就是先让子节点的add乘父节点的mul,再加上父节点的add)。sum[子节点]要先乘mul[父节点],再加上add[父节点]*(r-l+1)。

    理清了两种标记之间的关系,剩下的就是线段树板子了。这里要注意建树的时候,mul[k]初始值为1,add[k]初始值为0。

    代码:

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const ll N=100009;
    ll n,m,p;
    ll val[N*4],sum[N*4],add[N*4],mul[N*4];
    ll read()
    {
        char ch=getchar();
        ll x=0;bool f=0;
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')f=1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=(x<<3)+(x<<1)+(ch^48);
            ch=getchar();
        }
        if(f)x=-x;
        return x;
    }
    void build(ll k,ll l,ll r)
    {
        mul[k]=1;
        if(l==r)
        {
            sum[k]=val[r];    
            return ;
        }
        ll mid=(l+r)>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
        sum[k]=(sum[k<<1]+sum[k<<1|1]+p)%p;
        return;
    }
    void change(ll k,ll l,ll r,ll u)
    {
            add[k]=(mul[u]*add[k]%p+add[u])%p;//记得随时%p
        mul[k]=(mul[k]*mul[u])%p;
        sum[k]=(sum[k]*mul[u]%p+add[u]*(r-l+1)%p)%p;
    }
    void pushdown(ll k,ll l,ll r)//标记下传
    {
        ll mid=(l+r)>>1;
        change(k<<1,l,mid,k);
        change(k<<1|1,mid+1,r,k);
        add[k]=0;
        mul[k]=1;
        return;
    }
    void Mul(ll k,ll l,ll r,ll x,ll y,ll v)
    {
        if(l>=x&&r<=y)
        {
            mul[k]=(mul[k]*v)%p;
            add[k]=(add[k]*v)%p;
            sum[k]=(sum[k]*v)%p;
            return ;
        }
        pushdown(k,l,r);
        ll mid=(l+r)>>1;
        if(x<=mid)
          Mul(k<<1,l,mid,x,y,v);
        if(mid<y)  
          Mul(k<<1|1,mid+1,r,x,y,v);
        sum[k]=(sum[k<<1]+sum[k<<1|1]+p)%p;
        return;  
    }
    void Add(ll k,ll l,ll r,ll x,ll y,ll v)
    {
        if(l>=x&&r<=y)
        {
            add[k]=add[k]+v;
            sum[k]=(sum[k]+v*(r-l+1)%p)%p;    
            return ;
        }
    
        pushdown(k,l,r);
        ll mid=(l+r)>>1;
        if(x<=mid)
          Add(k<<1,l,mid,x,y,v);
        if(mid<y)
          Add(k<<1|1,mid+1,r,x,y,v);
        sum[k]=(sum[k<<1]+sum[k<<1|1]+p)%p;
        return ;        
    }
    ll query(ll k,ll l,ll r,ll x,ll y)
    {
        if(l>=x&&r<=y)
            return sum[k]%p;
        pushdown(k,l,r);
        ll mid=(l+r)>>1;
        ll ans=0;
        if(x<=mid)
          ans+=query(k<<1,l,mid,x,y);
        if(mid<y)
          ans+=query(k<<1|1,mid+1,r,x,y);
        return (ans+p)%p;    //防止出现负数
    }
    int main()
    {
        n=read();m=read();p=read();
        for(int i=1;i<=n;i++)
          val[i]=read()%p;
        build(1,1,n);
        for(int i=1;i<=N*4;i++)
         mul[i]=1;
        for(int i=1;i<=m;i++)
        {
            ll cz,x,y;
            cz=read();x=read();y=read();
            if(cz==1)
            {
                ll k=read();
                Mul(1,1,n,x,y,k);
            }
            if(cz==2)
            {
                ll k=read();
                Add(1,1,n,x,y,k);
            }
            if(cz==3)
            {
                printf("%lld
    ",query(1,1,n,x,y));
            }
        }  
    }
  • 相关阅读:
    20200226 Java IO流——廖雪峰
    20200225 Java 多线程(2)-廖雪峰
    20200225 Java 多线程(1)-廖雪峰
    20200224 尚硅谷ElasticSearch【归档】
    20200224 一 概述
    20200222 尚硅谷Dubbo【归档】
    20200222 四、dubbo原理
    Improved robustness of reinforcement learning policies upon conversion to spiking neuronal network platforms applied to Atari Breakout game
    Reinforcement learning in populations of spiking neurons
    Solving the Distal Reward Problem through Linkage of STDP and Dopamine Signaling
  • 原文地址:https://www.cnblogs.com/lcez56jsy/p/11112130.html
Copyright © 2011-2022 走看看