bzoj1798维护序列

Posted cn-suqingnian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj1798维护序列相关的知识,希望对你有一定的参考价值。

题目链接

暴力数据结构之线段树$qwq$

裸题直接敲板子

忘了啥时候写的了$qwq$

直接上代码吧

/**************************************************************
    Problem: 1798
    User: zhangheran
    Language: C++
    Result: Accepted
    Time:6372 ms
    Memory:10688 kb
****************************************************************/
 
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int n;
int m;
long long  mod;
struct lt
{
     long long val[400010];
     long long lazy[400010];
     long long lazzy[400010];
     inline void update(int p,int l,int r)
     {
         val[p]*=lazzy[p];
         val[p]%=mod;
         val[p]+=lazy[p]*(r-l);
         val[p]%=mod;
         return;
     }
     inline void pushdown(int p,int l,int r)
     {
         update(p,l,r);
         if(r-l>1)
         {
             lazy[2*p]*=lazzy[p];
             lazy[2*p]+=lazy[p];
             lazy[2*p]%=mod;
             lazzy[2*p]*=lazzy[p];
             lazzy[2*p]%=mod;
             lazy[2*p+1]*=lazzy[p];
             lazy[2*p+1]+=lazy[p];
             lazy[2*p+1]%=mod;
             lazzy[2*p+1]*=lazzy[p];
             lazzy[2*p+1]%=mod;
        }lazy[p]=0;
        lazzy[p]=1;
        return;
     }
     ll build(int p,int l,int r)
     {
         lazzy[p]=1;
         if(r-l==1)
         {
             scanf("%lld",&val[p]);
             val[p]%=mod;
             return val[p];
         }
        int mid=(l+r)/2;
        if(mid>l)val[p]+=build(2*p,l,mid);
        if(mid<r)val[p]+=build(2*p+1,mid,r);
        val[p]%=mod;
        return val[p];
     }
     void setplus(int p,int l,int r,int dl,int dr,long long plus)
     {
        if(lazy[p]!=0||lazzy[p]!=1) pushdown(p,l,r);
        if(l==dl&&r==dr)
        {
            lazy[p]+=plus;
             lazy[p]%=mod;
             pushdown(p,l,r);
             return;
        }
        int mid=(l+r)/2;
        if(mid>dl) setplus(2*p,l,mid,dl,min(mid,dr),plus);
        else pushdown(2*p,l,mid);
        if(mid<dr) setplus(2*p+1,mid,r,max(mid,dl),dr,plus);
        else pushdown(2*p+1,mid,r);
        val[p]=(val[2*p]+val[2*p+1])%mod;
        return;
     }
     void setmult(int p,int l,int r,int dl,int dr,long long mult)
     {
        if(lazzy[p]!=1||lazy[p]!=0)pushdown(p,l,r); 
        if(l==dl&&r==dr)
        {
            lazy[p]*=mult;
            lazzy[p]*=mult;
            lazy[p]%=mod;
            lazzy[p]%=mod;
            pushdown(p,l,r);
            return;
        }
        int mid=(l+r)/2;
        if(mid>dl) setmult(2*p,l,mid,dl,min(mid,dr),mult);
        else pushdown(2*p,l,mid);
        if(mid<dr)setmult(2*p+1,mid,r,max(mid,dl),dr,mult);
        else pushdown(2*p+1,mid,r);
        val[p]=(val[2*p]+val[2*p+1])%mod;
        return;
     }
     ll sum(int p,int l,int r,int dl,int dr)
     {
         if(lazy[p]!=0||lazzy[p]!=1) pushdown(p,l,r);
         if(l==dl&&r==dr) return val[p];
         int mid=(l+r)/2;
         ll res=0;
         if(mid>dl) res+=sum(2*p,l,mid,dl,min(mid,dr));
         if(mid<dr) res+=sum(2*p+1,mid,r,max(mid,dl),dr);
         res%=mod;
         return res;
     }
}lt;
int main()
{
    scanf("%d%d",&n,&mod);
    lt.build(1,0,n);scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        int opt,u,v;
        scanf("%d%d%d",&opt,&u,&v);
        if(opt==1)
        {
            int t;
            scanf("%d",&t);
            lt.setmult(1,0,n,u-1,v,t);    
        }
        else if(opt==2)
        {
            int t;
            scanf("%d",&t);
            lt.setplus(1,0,n,u-1,v,t);
        }
        else if(opt==3)
            printf("%lld
",lt.sum(1,0,n,u-1,v));
    }
    return 0;
}

 

以上是关于bzoj1798维护序列的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 1798 Seq 维护序列seq —— 线段树

BZOJ 1798 AHOI2009 Seq 维护序列 线段树

BZOJ1798题解 Seq维护序列题解 双tag裸线段树

bzoj1798: [Ahoi2009]Seq 维护序列seq 2011-12-20

BZOJ1798: [Ahoi2009]Seq 维护序列seq[线段树]

BZOJ1798 [Ahoi2009]Seq 维护序列seq