线段树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
- 线段树2(带有乘法标记)
- 线段树lazy标记2
- 线段树 延迟标记
- 线段树lazy标记
- 区间更新 区间和查询 带有延迟标记 线段树 hdu1698; 附:csa 区间加值,维护最大值
- 线段树单标记,双标记
- zkw线段树 标记下放
- 线段树_懒标记
- 线段树lazy标记??Hdu4902
- 线段树的标记lazy_tag
- hdu 3954 线段树 (标记)
- POJ 3667 线段树+标记
- HDU1698(线段树+延迟标记)
- Transformation(线段树 + lazy 标记)
- ZOJ(矩阵乘法+线段树)
- Codeforces719E 矩阵乘法+线段树
- 线段树乘法取%版
- [线段树练习2] 影子的宽度 - 统计标记个数
- 立体匹配文献阅读笔记(一)《A non-local cost aggregation method for stereo matching》12年
- 电子电路基础知识——电阻,电容,电感
- 黑苹果引导工具 Clover 配置详解及Clover Configurator使用
- jdbc
- Zurmo(十一)Relation之n:n和1:n(二)
- 线段树2(带有乘法标记)
- c中共用体简谈
- unit1
- css关于文字属性
- uva 673 Parentheses Balance (平衡的括号)堆栈模拟
- word中使用bibtex4word插入参考文献。
- 阿里面试心得
- 《Linux/UNIX系统编程手册》第3章读书笔记
- 快排原理