ahoi2009维护序列

链接:https://www.luogu.org/problemnew/show/P2023

裸的线段树维护+*

代码:

#include <bits/stdc++.h>
using namespace std;
#define maxn 400010
#define mid (h+t)/2
#define ll long long
ll n,m,a[maxn],mo,c,d,e,lazy1[maxn],lazy2[maxn];
struct re
{
    ll h,t,x;
}p[maxn];
void updata(ll x)
{
    p[x].x=(p[x*2].x+p[x*2+1].x)%mo;
}
void build(ll x,ll h,ll t)
{
    p[x].h=h; p[x].t=t;
    if (h==t)
    {
        p[x].x=a[h]; return;
    }
    build(x*2,h,mid); build(x*2+1,mid+1,t);
    updata(x);
}
void down(ll x)
{
  if (lazy2[x]!=1)
  {
      p[x].x=(p[x].x*lazy2[x])%mo;
      if (p[x].h!=p[x].t) //这一句效率有明显提高
      {
      lazy2[x*2]=(lazy2[x*2]*lazy2[x])%mo;
      lazy2[x*2+1]=(lazy2[x*2+1]*lazy2[x])%mo;
      lazy1[x*2]=(lazy1[x*2]*lazy2[x])%mo;
      lazy1[x*2+1]=(lazy1[x*2+1]*lazy2[x])%mo;
    }}
    if (lazy1[x])
    {
        p[x].x=(p[x].x+lazy1[x]*(p[x].t-p[x].h+1))%mo;
      if (p[x].h!=p[x].t)
      {
        lazy1[x*2]=(lazy1[x*2]+lazy1[x])%mo;
        lazy1[x*2+1]=(lazy1[x*2+1]+lazy1[x])%mo;
    }}
    lazy1[x]=0; lazy2[x]=1;
}
void change1(ll x,ll h,ll t,ll num)
{
    down(x);
    if (p[x].h>t||p[x].t<h) return;
    if (h<=p[x].h&&p[x].t<=t)
    {
        lazy1[x]=(lazy1[x]+num)%mo;
        down(x); 
        return;
    }
    change1(x*2,h,t,num); change1(x*2+1,h,t,num);
    updata(x);
}
void change2(ll x,ll h,ll t,ll num)
{
    down(x);
    if (p[x].h>t||p[x].t<h) return;
    if (h<=p[x].h&&p[x].t<=t)
    {
        lazy1[x]=(lazy1[x]*num)%mo;
        lazy2[x]=(lazy2[x]*num)%mo;
        down(x);
        return;
    }
    change2(x*2,h,t,num); change2(x*2+1,h,t,num);
    updata(x);
}
ll query(ll x,ll h,ll t)
{
    down(x);
    if (p[x].h>t||p[x].t<h) return(0);
    if (h<=p[x].h&&p[x].t<=t) return(p[x].x);
    return((query(x*2,h,t)+query(x*2+1,h,t))%mo); 
}
int main()
{
    std::ios::sync_with_stdio(false);
    cin>>n>>m>>mo;
    for (ll i=1;i<=n;i++) cin>>a[i];
    for (int i=1;i<=maxn-1;i++) lazy2[i]=1;
    build(1,1,n);
    for (ll i=1;i<=m;i++)
    {
        int c,d,e,f;
        cin>>c;
        if (c==1)
        {
            cin>>d>>e>>f;
            change2(1,d,e,f);
        }
      if (c==2)
      {
          cin>>d>>e>>f;
          change1(1,d,e,f);
        }
        if (c==3)
        {
            cin>>d>>e;
            cout<<query(1,d,e)%mo<<endl;
        }
    }
    return 0; 
}

 

posted @ 2018-01-30 23:19  尹吴潇  阅读(132)  评论(0编辑  收藏  举报