线段树2(带有乘法标记)

来源:互联网 发布:mac office 2011 汉化 编辑:程序博客网 时间:2024/05/20 22:37

传送门:线段树2

洛谷好像有点卡常数…
少模几次然后改一个操作的位置这种细节型的东西才可以过。
其实和线段树1的差别也不是很大
1.很多数组开long long ,不然肯定会爆(要打快速乘我也没办法)
2.添加加法标记的时候和线段树1一样,添加乘法标记的时候要把以前的乘法标记、加法标记、记录的和乘上这个标记就可以了
3.下推标记的时候孩子节点的所有标记也要乘上乘法标记
然后其实剩下的就和线段树1差不多了。

#include<cstdio>template <typename Type> inline void Read(Type &in){    in=0;Type f=1;char ch=getchar();    for( ; ch>'9'  || ch<'0'  ; ch=getchar() ) if( ch == '-' ) f=-1;    for( ; ch>='0' && ch<='9' ; ch=getchar() ) in=in *10 + ch-'0'; in*=f;}const int MAXN = 100001<<2;typedef long long LL;int n,m,Mod;LL Sum[MAXN],Add[MAXN],Mul[MAXN];void Up( int Nd ){    Sum[Nd] = ( Sum[Nd<<1] + Sum[Nd<<1|1] ) %Mod;}void Build( int Nd , int TL , int TR ){    if( TL == TR ){        Read ( Sum[Nd] );        Sum[Nd] %= Mod;        return ;    }    int Mid = ( TL + TR ) >>1;    Build( Nd<<1   , TL   , Mid );    Build( Nd<<1|1 , Mid+1, TR );    Mul[Nd] = 1;    Up( Nd );}void UD( int Nd , int TL , int TR ){    if( !Add[Nd] && Mul[Nd] == 1) return ;    int lc = Nd<<1 , rc = Nd<<1|1;    Mul[lc] = (Mul[lc] * Mul[Nd]) %Mod;    Mul[rc] = (Mul[rc] * Mul[Nd]) %Mod;    Add[lc] = (Add[lc] * Mul[Nd]  + Add[Nd]) %Mod;    Add[rc] = (Add[rc] * Mul[Nd]  + Add[Nd]) %Mod;    Sum[lc] = (Sum[lc] * Mul[Nd]  + Add[Nd] * TL %Mod) %Mod;    Sum[rc] = (Sum[rc] * Mul[Nd]  + Add[Nd] * TR %Mod) %Mod;    Add[Nd] = 0;    Mul[Nd] = 1;}void UA( int Nd , int TL , int TR , int l , int r , LL k ){    if( TL > r || TR < l ) return ;    if( TL >=l && TR <=r ){        Add[Nd] = (Add[Nd] + k) %Mod;        Sum[Nd] = (Sum[Nd] + k*(TR - TL + 1) ) %Mod;        return ;    }    int Mid = ( TL + TR ) >>1;    UD( Nd,     Mid - TL + 1 , TR - Mid);    UA( Nd<<1   , TL   , Mid , l , r , k );    UA( Nd<<1|1 , Mid+1, TR  , l , r , k );    Up( Nd );}void UM( int Nd , int TL , int TR , int l , int r , LL k ){    if( TL > r || TR < l ) return ;    if( TL >=l && TR <=r ){        Mul[Nd] = (Mul[Nd] * k) %Mod;        Add[Nd] = (Add[Nd] * k) %Mod;        Sum[Nd] = (Sum[Nd] * k) %Mod;        return ;    }    int Mid = ( TL + TR ) >>1;    UD( Nd,     Mid - TL + 1 , TR - Mid);    UM( Nd<<1   , TL   , Mid , l , r , k );    UM( Nd<<1|1 , Mid+1, TR  , l , r , k );    Up( Nd );}LL Query( int Nd , int TL , int TR ,int l , int r){    if( TL > r || TR < l ) return 0;    if( TL >=l && TR <=r ) return Sum[Nd]%Mod;    int Mid = ( TL + TR ) >>1;    UD( Nd , Mid - TL + 1 ,TR - Mid);    return (Query( Nd<<1   , TL   , Mid , l , r )           +Query( Nd<<1|1 , Mid+1, TR  , l , r ))%Mod;}int main(){    Read( n ); Read( m );  Read ( Mod );    Build ( 1, 1, n );    while( m-- ){        int Opt , l , r , k;        Read( Opt ) ; Read ( l ) ; Read( r ) ;        if( Opt == 3 ) printf("%lld\n",Query( 1 , 1 , n , l , r ));        else{            Read ( k );            k %= Mod;            if( Opt == 1 )                UM( 1 , 1 , n , l , r , k );            else                UA( 1 , 1 , n , l , r , k );        }    }    return 0;}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 口腔黏膜破了怎么办 有鼻炎鼻子痒怎么办 感冒就清鼻涕怎么办 怀孕感冒流鼻涕打喷嚏怎么办 过敏性鼻炎打喷嚏流鼻涕怎么办 宝宝黄鼻涕鼻塞怎么办 鼻炎总是打喷嚏流鼻涕怎么办 新生儿流黄鼻涕怎么办 感冒鼻塞流鼻涕喷嚏怎么办 宝宝总是打喷嚏流鼻涕怎么办 不停的打喷嚏流鼻涕怎么办 宝宝不停打喷嚏流鼻涕怎么办 孕妇感冒流鼻涕打喷嚏怎么办 孕妇感冒咳嗽流鼻涕怎么办 鼻子痒流鼻涕流眼泪怎么办 天冷鼻子流鼻涕怎么办 感冒流水样鼻涕怎么办 一直有清水鼻涕怎么办 孩子总打喷嚏鼻塞怎么办 4岁儿童流鼻涕怎么办 孕妇清鼻涕不停怎么办 感冒流鼻水怎么办速效办法 一岁宝宝流清涕怎么办 咳嗽喉咙痛有痰怎么办 冻感冒了流鼻涕怎么办 吸烟经常嗓子疼怎么办 擦鼻涕擦破了怎么办 感冒鼻水流不停怎么办 流鼻涕鼻子都擦红了怎么办 鼻子不停的流水怎么办 擦鼻涕耳朵疼怎么办 鼻涕跟水一样怎么办 鼻涕水多打喷嚏怎么办 买来的鼻涕泥是水怎么办? 鼻炎鼻涕跟水怎么办 出门忘记带钥匙怎么办 总留鼻涕水怎么办 流像水一样的鼻涕怎么办 出门忘记带洗面奶怎么办 一侧鼻子流清水怎么办 慢性肠胃炎犯了怎么办