码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj1798维护序列

时间:2018-07-25 00:54:46      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:bzoj1798   show   线段   pac   long   push   span   ret   inline   

题目链接

暴力数据结构之线段树$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\n",lt.sum(1,0,n,u-1,v));
    }
    return 0;
}

 

bzoj1798维护序列

标签:bzoj1798   show   线段   pac   long   push   span   ret   inline   

原文地址:https://www.cnblogs.com/cn-suqingnian/p/9363438.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!