#ifndef INCLUDE_MODE #define INCLUDE_MODE /* #define SUBMIT_ONLY */ #define DEBUG_OUTPUT #endif #ifdef INCLUDE_MAIN VO Solve() { CIN( int , N , Q ); CIN( string , S ); CIN_A( int , 0 , N + 1 , W ); vector X_pre( N + 1 ); FOREQ( i , 1 , N ){ X_pre[i] = S[i-1] == 'B'; } IntervalMultiplyLazySqrtDecomposition X{ MultiplicativeMonoid{ 1 } , Module{} , move( X_pre ) } , Y{ MultiplicativeMonoid{ 1 } , Module{} , move( W ) }; FOR( q , 0 , Q ){ CIN( int , type ); if( type == 1 ){ CIN( int , l , r ); X.IntervalAct( l , r , -1 ); X.IntervalMultiply( l , r , 1 ); } else if( type == 2 ){ CIN( int , l , r , a ); Y.IntervalMultiply( l , r , a ); } else if( type == 3 ){ CIN( int , v , K ); CIN_A( int , 0 , K , u ); int v_next = X.Search( v , 1 ); if( v_next == -1 ){ v_next = N; } int num = Y.IntervalProduct( v , v_next ) , den = Y.IntervalProduct( 0 , v_next ); int k0 = 0; while( k0 < K && u[k0] < v ){ k0++; } int k1 = k0; while( k1 < K && u[k1] <= v_next ){ k1++; } vector a( K + 1 ); if( num == den ){ assert( v == 0 && k0 == 0 ); a[K] = 1; } else { vector multiplicity( K + 1 ); int k_prev = k1; FOREQ( k , k1 + 1 , K ){ if( k == K || X.IntervalProduct( u[k-1] , u[k] - 1 ) > 0 ){ multiplicity[k-k_prev]++; k_prev = k; } } MP r = MP{ num } / MP{ den - num }; FPS log{ K + 1 }; FOREQ( k , 1 , K ){ if( multiplicity[k] > 0 ){ MP power = multiplicity[k]; FOREQ( d , k , K , k ){ power *= r; int i = d / k; log[d] += ( i & 1 ? 1 : -1 ) * power / i; } } } FPS f = Exp( log ) * Power( MP{ den - num } / MP{ den } , Sum( multiplicity ) ); FOREQ( k , k1 - k0 , K ){ a[k] = f[k-(k1-k0)]; } } COUT( a ); } } } REPEAT_MAIN(1); #else /* INCLUDE_MAIN */ #ifdef INCLUDE_SUB /* 圧縮時は中身だけ削除する。*/ IN VO Experiment() { } /* 圧縮時は中身だけ削除する。*/ IN VO SmallTest() { CERR( "全てのケースを確認しました。" ); } /* 圧縮時は中身だけ削除する。*/ IN VO RandomTest( const int& test_case_num ) { REPEAT( test_case_num ){ } CERR( "全てのケースを確認しました。" ); } #define INCLUDE_MAIN #include __FILE__ #else /* INCLUDE_SUB */ #ifdef INCLUDE_LIBRARY /* VVV 常設でないライブラリは以下に挿入する。*/ #ifdef DEBUG #include "c:/Users/user/Documents/Programming/Mathematics/SetTheory/DirectProduct/AffineSpace/SqrtDecomposition/LazyEvaluation/IntervalMultiply/a_Body.hpp" #else TE CL VirtualBiModule:VI PU UnderlyingSet{PU:VI U LAction(CO L& l,U u)= 0;VI U RAction(U u,CO R& r)= 0;IN U ScalarProduct(CO L& l,U u);IN U PW(U u,CO R& r);};TE CL AbstractBiModule:PU VirtualBiModule,PU GROUP{PU:O_U_L m_o_U_L;O_U_R m_o_U_R;IN AbstractBiModule(CO L& dummy_l,CO R& dummy_r,O_U_L o_U_L,O_U_R o_U_R,GROUP M);IN AbstractBiModule& OP=(CO AbstractBiModule&)NE;IN U LAction(CO L& l,U u);IN U RAction(U u,CO R& r);};TE AbstractBiModule(CO L& dummy_l,CO R& dummy_r,O_U_L o_U_L,O_U_R o_U_R,GROUP M)-> AbstractBiModule,O_U_L,O_U_R,GROUP>;TE CL BiModule:VI PU VirtualBiModule,PU AdditiveGroup{PU:IN U LAction(CO L& r,U u);IN U RAction(U u,CO R& r);}; TE IN AbstractBiModule::AbstractBiModule(CO L& dummy_l,CO R& dummy_r,O_U_L o_U_L,O_U_R o_U_R,GROUP M):GROUP(MO(M)),m_o_U_L(MO(o_U_L)),m_o_U_R(MO(o_U_R)){ST_AS(is_same_v> && is_invocable_r_v && is_invocable_r_v);}TE IN U AbstractBiModule::LAction(CO L& l,U u){RE m_o_U_L(l,MO(u));}TE IN U BiModule::LAction(CO L& l,U u){RE MO(u *= l);}TE IN U AbstractBiModule::RAction(U u,CO R& r){RE m_o_U_R(MO(u),r);}TE IN U BiModule::RAction(U u,CO R& r){RE MO(u *= r);}TE IN U VirtualBiModule::ScalarProduct(CO L& l,U u){RE LAction(l,MO(u));}TE IN U VirtualBiModule::PW(U u,CO R& r){RE RAction(MO(u),r);} CL SqrtDecompositionCoordinate{PU:int m_N;int m_N_sqrt;int m_N_d;int m_N_m;IN SqrtDecompositionCoordinate(CRI N = 0);IN SqrtDecompositionCoordinate(CRI N,CRI N_sqrt);IN CRI size()CO NE;IN CRI BucketSize()CO NE;IN CRI BucketCount()CO NE;}; IN SqrtDecompositionCoordinate::SqrtDecompositionCoordinate(CRI N):SqrtDecompositionCoordinate(N,RoundUpSqrt(N)){};IN SqrtDecompositionCoordinate::SqrtDecompositionCoordinate(CRI N,CRI N_sqrt):m_N(N),m_N_sqrt(N_sqrt),m_N_d((m_N + m_N_sqrt - 1)/ m_N_sqrt),m_N_m(m_N_d * m_N_sqrt){}IN CRI SqrtDecompositionCoordinate::size()CO NE{RE m_N;}IN CRI SqrtDecompositionCoordinate::BucketSize()CO NE{RE m_N_sqrt;}IN CRI SqrtDecompositionCoordinate::BucketCount()CO NE{RE m_N_d;} #define SFINAE_FOR_SD_S enable_if_t>* TE ,TY U = inner_t>CL IntervalMultiplyLazySqrtDecomposition:PU SqrtDecompositionCoordinate{PU:PT_MAGMA m_L;RN_BIMODULE m_M;VE m_a;VE m_b;VE m_lazy_substitution;VE m_suspended;VE m_lazy_action;VE m_lazy_MU;TE IN IntervalMultiplyLazySqrtDecomposition(PT_MAGMA L,RN_BIMODULE M,CRI N = 0,CO Args&... args);TE IN IntervalMultiplyLazySqrtDecomposition(PT_MAGMA L,RN_BIMODULE M,VE a,CO Args&... args);TE IN VO Initialise(Args&&... args);IN VO Set(CRI i,CO U& u);IN VO IntervalSet(CRI i_start,CRI i_final,CO U& u);IN VO IntervalAct(CRI i_start,CRI i_final,CO R& r);IN VO IntervalMultiply(CRI i_start,CRI i_final,CO U& u);IN U OP[](CRI i);IN U Get(CRI i);IN U IntervalProduct(CRI i_start,CRI i_final);TE IN int Search(CRI i_start,CO F& f,CO bool& reversed = false);IN int Search(CRI i_start,CO U& u,CO bool& reversed = false);IN VO COruct();IN VO SetProduct(CRI i);IN VO SolveSuspendedSubstitution(CRI d,CO U& u);IN VO IntervalSet_Body(CRI i_min,CRI i_ulim,CO U& u);IN VO SolveSuspendedAction(CRI d);IN VO IntervalAct_Body(CRI i_min,CRI i_ulim,CO R& r);IN VO IntervalMultiply_Body(CRI i_min,CRI i_ulim,CO U& u);IN U IntervalProduct_Body(CRI i_min,CRI i_ulim);TE int Search_Body(CRI i_start,CO F& f,U product_temp);TE int SearchReverse_Body(CRI i_final,CO F& f,U sum_temp);}; TE TE IN IntervalMultiplyLazySqrtDecomposition::IntervalMultiplyLazySqrtDecomposition(PT_MAGMA L,RN_BIMODULE M,CRI N,CO Args&... args):SqrtDecompositionCoordinate(N,args...),m_L(MO(L)),m_M(MO(M)),m_a(N,m_M.One()),m_b(m_N_d,m_M.One()),m_lazy_substitution(m_b),m_suspended(m_N_d),m_lazy_action(m_N_d,m_L.Point()),m_lazy_MU(m_b){COruct();}TE TE IN IntervalMultiplyLazySqrtDecomposition::IntervalMultiplyLazySqrtDecomposition(PT_MAGMA L,RN_BIMODULE M,VE a,CO Args&... args):SqrtDecompositionCoordinate(a.SZ(),args...),m_L(MO(L)),m_M(MO(M)),m_a(MO(a)),m_b(m_N_d,m_M.One()),m_lazy_substitution(m_b),m_suspended(m_N_d),m_lazy_action(m_N_d,m_L.Point()),m_lazy_MU(m_b){COruct();}TE IN VO IntervalMultiplyLazySqrtDecomposition::COruct(){ST_AS(is_same_v> && is_same_v>);m_a.resize(m_N_m,m_M.One());int i_min = 0;int i_ulim = m_N_sqrt;for(int d = 0;d < m_N_d;d++){U& m_bd = m_b[d];for(int i = i_min;i < i_ulim;i++){m_bd = m_M.Product(MO(m_bd),m_a[i]);}i_min = i_ulim;i_ulim += m_N_sqrt;}}TE TE IN VO IntervalMultiplyLazySqrtDecomposition::Initialise(Args&&...args){IntervalMultiplyLazySqrtDecomposition temp{m_L,m_M,forward(args)...};SqrtDecompositionCoordinate::OP=(temp);m_a = MO(temp.m_a);m_b = MO(temp.m_b);m_lazy_substitution = MO(temp.m_lazy_substitution);m_suspended = MO(temp.m_suspended);m_lazy_action = MO(temp.m_lazy_action);m_lazy_MU = MO(temp.m_lazy_MU);}TE IN VO IntervalMultiplyLazySqrtDecomposition::Set(CRI i,CO U& u){CO int d = i / m_N_sqrt;U& m_ai = m_a[i];U& m_bd = m_b[d];if(m_suspended[d]){U& m_lazy_substitution_d = m_lazy_substitution[d];if(m_lazy_substitution_d != u){SolveSuspendedSubstitution(d,m_lazy_substitution_d);m_ai = u;m_bd = m_M.Product(m_M.Power(m_lazy_substitution_d,m_N_sqrt - 1),u);}}else{SolveSuspendedAction(d);if(m_ai != u){m_ai = u;SetProduct(d);}}RE;}TE IN VO IntervalMultiplyLazySqrtDecomposition::IntervalSet(CRI i_start,CRI i_final,CO U& u){CO int i_min = max(i_start,0);CO int i_ulim = min(i_final + 1,m_N);CO int d_0 =(i_min + m_N_sqrt - 1)/ m_N_sqrt;CO int d_1 = max(d_0,i_ulim / m_N_sqrt);CO int d_0_N_sqrt = d_0 * m_N_sqrt;CO int d_1_N_sqrt = d_1 * m_N_sqrt;CO int i_0 = min(d_0_N_sqrt,i_ulim);CO int i_1 = max(i_0,d_1_N_sqrt);if(i_min < i_0){CO int d_0_minus = d_0 - 1;CO int d_0_N_sqrt_minus = d_0_N_sqrt - m_N_sqrt;U& m_bd = m_b[d_0_minus];VE::reference m_suspended_d = m_suspended[d_0_minus];if(m_suspended_d){CO U& m_lazy_substitution_d = m_lazy_substitution[d_0_minus];IntervalSet_Body(d_0_N_sqrt_minus,i_min,m_lazy_substitution_d);IntervalSet_Body(i_min,i_0,u);IntervalSet_Body(i_0,d_0_N_sqrt,m_lazy_substitution_d);m_suspended_d = false;m_bd = m_M.Product(m_M.Power(m_lazy_substitution_d,m_N_sqrt -(i_0 - i_min)),m_M.Power(u,i_0 - i_min));}else{SolveSuspendedAction(d_0_minus);IntervalSet_Body(i_min,i_0,u);m_bd = m_M.Product(m_M.Product(IntervalProduct_Body(d_0_N_sqrt_minus,i_min),m_M.Power(u,i_0 - i_min)),IntervalProduct_Body(i_0,d_0_N_sqrt));}}CO U pw = m_M.Power(u,m_N_sqrt);CO U& one = m_M.One();CO R& point = m_L.Point();for(int d = d_0;d < d_1;d++){m_b[d]= pw;m_lazy_substitution[d]= u;m_suspended[d]= true;m_lazy_MU[d]= one;m_lazy_action[d]= point;}if(i_1 < i_ulim){CO int d_1_N_sqrt_plus = d_1_N_sqrt + m_N_sqrt;U& m_bd = m_b[d_1];VE::reference m_suspended_d = m_suspended[d_1];if(m_suspended_d){CO U& m_lazy_substitution_d = m_lazy_substitution[d_1];IntervalSet_Body(d_1_N_sqrt,i_1,m_lazy_substitution_d);IntervalSet_Body(i_1,i_ulim,u);IntervalSet_Body(i_ulim,d_1_N_sqrt_plus,m_lazy_substitution_d);m_suspended_d = false;m_bd = m_M.Product(m_M.Product(m_M.Power(m_lazy_substitution_d,i_1 - d_1_N_sqrt),m_M.Power(u,i_ulim - i_1)),m_M.Power(m_lazy_substitution_d,d_1_N_sqrt_plus - i_ulim));}else{SolveSuspendedAction(d_1);IntervalSet_Body(i_1,i_ulim,u);m_bd = m_M.Product(m_M.Product(IntervalProduct_Body(d_1_N_sqrt,i_1),m_M.Power(u,i_ulim - i_1)),IntervalProduct_Body(i_ulim,d_1_N_sqrt_plus));}}RE;}TE IN VO IntervalMultiplyLazySqrtDecomposition::IntervalAct(CRI i_start,CRI i_final,CO R& r){CO R& point = m_L.Point();if(r != point){CO U& one = m_M.One();CO int i_min = max(i_start,0);CO int i_ulim = min(i_final + 1,m_N);CO int d_0 =(i_min + m_N_sqrt - 1)/ m_N_sqrt;CO int d_1 = max(d_0,i_ulim / m_N_sqrt);CO int d_0_N_sqrt = d_0 * m_N_sqrt;CO int d_1_N_sqrt = d_1 * m_N_sqrt;CO int i_0 = min(d_0_N_sqrt,i_ulim);CO int i_1 = max(i_0,d_1_N_sqrt);if(i_min < i_0){CO int d_0_minus = d_0 - 1;CO int d_0_N_sqrt_minus = d_0_N_sqrt - m_N_sqrt;VE::reference m_suspended_d = m_suspended[d_0_minus];if(m_suspended_d){CO U& m_lazy_substitution_d = m_lazy_substitution[d_0_minus];U& m_bd = m_b[d_0_minus];CO U u = m_M.ScalarProduct(r,m_lazy_substitution_d);IntervalSet_Body(d_0_N_sqrt_minus,i_min,m_lazy_substitution_d);IntervalSet_Body(i_min,i_0,u);IntervalSet_Body(i_0,d_0_N_sqrt,m_lazy_substitution_d);m_suspended_d = false;m_bd = m_M.Product(m_M.Power(m_lazy_substitution_d,m_N_sqrt -(i_0 - i_min)),m_M.Power(u,i_0 - i_min));}else{R& m_lazy_action_d = m_lazy_action[d_0_minus];if(m_lazy_action_d == point){IntervalAct_Body(i_min,i_0,r);}else{IntervalAct_Body(d_0_N_sqrt_minus,i_min,m_lazy_action_d);IntervalAct_Body(i_min,i_0,m_L.Product(r,m_lazy_action_d));IntervalAct_Body(i_0,d_0_N_sqrt,m_lazy_action_d);m_lazy_action_d = point;}U& m_lazy_MU_d = m_lazy_MU[d_0_minus];if(m_lazy_MU_d != one){IntervalMultiply_Body(d_0_N_sqrt_minus,i_min,m_lazy_MU_d);IntervalMultiply_Body(i_min,i_0,m_M.ScalarProduct(r,m_lazy_MU_d));IntervalMultiply_Body(i_0,d_0_N_sqrt,m_lazy_MU_d);m_lazy_MU_d = one;}SetProduct(d_0_minus);}}for(int d = d_0;d < d_1;d++){U& m_bd = m_b[d];m_bd = m_M.ScalarProduct(r,m_bd);if(m_suspended[d]){U& m_lazy_substitution_d = m_lazy_substitution[d];m_lazy_substitution_d = m_M.ScalarProduct(r,m_lazy_substitution_d);}else{R& m_lazy_action_d = m_lazy_action[d];m_lazy_action_d = m_L.Product(r,m_lazy_action_d);U& m_lazy_MU_d = m_lazy_MU[d];m_lazy_MU_d = m_M.ScalarProduct(r,m_lazy_MU_d);}}if(i_1 < i_ulim){CO int d_1_N_sqrt_plus = d_1_N_sqrt + m_N_sqrt;VE::reference m_suspended_d = m_suspended[d_1];if(m_suspended_d){CO U& m_lazy_substitution_d = m_lazy_substitution[d_1];U& m_bd = m_b[d_1];CO U u = m_M.ScalarProduct(r,m_lazy_substitution_d);IntervalSet_Body(d_1_N_sqrt,i_1,m_lazy_substitution_d);IntervalSet_Body(i_1,i_ulim,u);IntervalSet_Body(i_ulim,d_1_N_sqrt_plus,m_lazy_substitution_d);m_suspended_d = false;m_bd = m_M.Product(m_M.Power(m_lazy_substitution_d,m_N_sqrt -(i_ulim - i_1)),m_M.Power(u,i_ulim - i_1));}else{R& m_lazy_action_d = m_lazy_action[d_1];if(m_lazy_action_d == point){IntervalAct_Body(i_1,i_ulim,r);}else{IntervalAct_Body(d_1_N_sqrt,i_1,m_lazy_action_d);IntervalAct_Body(i_1,i_ulim,m_L.Product(r,m_lazy_action_d));IntervalAct_Body(i_ulim,d_1_N_sqrt_plus,m_lazy_action_d);m_lazy_action_d = point;}U& m_lazy_MU_d = m_lazy_MU[d_1];if(m_lazy_MU_d != one){IntervalMultiply_Body(d_1_N_sqrt,i_1,m_lazy_MU_d);IntervalMultiply_Body(i_1,i_ulim,m_M.ScalarProduct(r,m_lazy_MU_d));IntervalMultiply_Body(i_ulim,d_1_N_sqrt_plus,m_lazy_MU_d);m_lazy_MU_d = one;}SetProduct(d_1);}}}RE;}TE IN VO IntervalMultiplyLazySqrtDecomposition::IntervalMultiply(CRI i_start,CRI i_final,CO U& u){CO U& one = m_M.One();if(u != one){CO R& point = m_L.Point();CO int i_min = max(i_start,0);CO int i_ulim = min(i_final + 1,m_N);CO int d_0 =(i_min + m_N_sqrt - 1)/ m_N_sqrt;CO int d_1 = max(d_0,i_ulim / m_N_sqrt);CO int d_0_N_sqrt = d_0 * m_N_sqrt;CO int d_1_N_sqrt = d_1 * m_N_sqrt;CO int i_0 = min(d_0_N_sqrt,i_ulim);CO int i_1 = max(i_0,d_1_N_sqrt);if(i_min < i_0){CO int d_0_minus = d_0 - 1;CO int d_0_N_sqrt_minus = d_0_N_sqrt - m_N_sqrt;U& m_bd = m_b[d_0_minus];m_bd = m_M.Product(MO(m_bd),m_M.Power(u,i_0 - i_min));VE::reference m_suspended_d = m_suspended[d_0_minus];if(m_suspended_d){CO U& m_lazy_substitution_d = m_lazy_substitution[d_0_minus];IntervalSet_Body(d_0_N_sqrt_minus,i_min,m_lazy_substitution_d);IntervalSet_Body(i_min,i_0,m_M.Product(m_lazy_substitution_d,u));IntervalSet_Body(i_0,d_0_N_sqrt,m_lazy_substitution_d);m_suspended_d = false;}else{R& m_lazy_action_d = m_lazy_action[d_0_minus];if(m_lazy_action_d != point){IntervalAct_Body(d_0_N_sqrt_minus,d_0_N_sqrt,m_lazy_action_d);m_lazy_action_d = point;}U& m_lazy_MU_d = m_lazy_MU[d_0_minus];if(m_lazy_MU_d == one){IntervalMultiply_Body(i_min,i_0,u);}else{IntervalMultiply_Body(d_0_N_sqrt_minus,i_min,m_lazy_MU_d);IntervalMultiply_Body(i_min,i_0,m_M.Product(m_lazy_MU_d,u));IntervalMultiply_Body(i_0,d_0_N_sqrt,m_lazy_MU_d);m_lazy_MU_d = one;}}}CO U pw = m_M.Power(u,m_N_sqrt);for(int d = d_0;d < d_1;d++){U& m_bd = m_b[d];m_bd = m_M.Product(MO(m_bd),pw);if(m_suspended[d]){U& m_lazy_substitution_d = m_lazy_substitution[d];m_lazy_substitution_d = m_M.Product(MO(m_lazy_substitution_d),u);}else{U& m_lazy_MU_d = m_lazy_MU[d];m_lazy_MU_d = m_M.Product(MO(m_lazy_MU_d),u);}}if(i_1 < i_ulim){CO int d_1_N_sqrt_plus = d_1_N_sqrt + m_N_sqrt;U& m_bd = m_b[d_1];m_bd = m_M.Product(MO(m_bd),m_M.Power(u,i_ulim - i_1));VE::reference m_suspended_d = m_suspended[d_1];if(m_suspended_d){CO U& m_lazy_substitution_d = m_lazy_substitution[d_1];IntervalSet_Body(d_1_N_sqrt,i_1,m_lazy_substitution_d);IntervalSet_Body(i_1,i_ulim,m_M.Product(m_lazy_substitution_d,u));IntervalSet_Body(i_ulim,d_1_N_sqrt_plus,m_lazy_substitution_d);m_suspended_d = false;}else{R& m_lazy_action_d = m_lazy_action[d_1];if(m_lazy_action_d != point){IntervalAct_Body(d_1_N_sqrt,d_1_N_sqrt_plus,m_lazy_action_d);m_lazy_action_d = point;}U& m_lazy_MU_d = m_lazy_MU[d_1];if(m_lazy_MU_d == one){IntervalMultiply_Body(i_1,i_ulim,u);}else{IntervalMultiply_Body(d_1_N_sqrt,i_1,m_lazy_MU_d);IntervalMultiply_Body(i_1,i_ulim,m_M.Product(m_lazy_MU_d,u));IntervalMultiply_Body(i_ulim,d_1_N_sqrt_plus,m_lazy_MU_d);m_lazy_MU_d = one;}}}}RE;}TE IN U IntervalMultiplyLazySqrtDecomposition::OP[](CRI i){AS(0 <= i && i < m_N);CO int d = i / m_N_sqrt;RE m_suspended[d]?m_lazy_substitution[d]:m_M.Product(m_M.ScalarProduct(m_lazy_action[d],m_a[i]),m_lazy_MU[d]);}TE IN U IntervalMultiplyLazySqrtDecomposition::Get(CRI i){RE OP[](i);}TE IN U IntervalMultiplyLazySqrtDecomposition::IntervalProduct(CRI i_start,CRI i_final){CO int i_min = max(i_start,0);CO int i_ulim = min(i_final + 1,m_N);CO int d_0 =(i_min + m_N_sqrt - 1)/ m_N_sqrt;CO int d_1 = max(d_0,i_ulim / m_N_sqrt);CO int i_0 = min(d_0 * m_N_sqrt,i_ulim);CO int i_1 = max(i_0,d_1 * m_N_sqrt);U AN = m_M.One();if(i_min < i_0){CO int d_0_minus = d_0 - 1;AN = m_suspended[d_0_minus]?m_M.Power(m_lazy_substitution[d_0_minus],i_0 - i_min):m_M.Product(m_M.ScalarProduct(m_lazy_action[d_0_minus],IntervalProduct_Body(i_min,i_0)),m_M.Power(m_lazy_MU[d_0_minus],i_0 - i_min));}for(int d = d_0;d < d_1;d++){AN = m_M.Product(MO(AN),m_b[d]);}if(i_1 < i_ulim){AN = m_M.Product(MO(AN),m_suspended[d_1]?m_M.Power(m_lazy_substitution[d_1],i_ulim - i_1):m_M.Product(m_M.ScalarProduct(m_lazy_action[d_1],IntervalProduct_Body(i_1,i_ulim)),m_M.Power(m_lazy_MU[d_1],i_ulim - i_1)));}RE AN;}TE IN VO IntervalMultiplyLazySqrtDecomposition::SetProduct(CRI d){U& m_bd = m_b[d]= m_M.One();CO int i_min = d * m_N_sqrt;CO int i_ulim = i_min + m_N_sqrt;for(int i = i_min;i < i_ulim;i++){m_bd = m_M.Product(MO(m_bd),m_a[i]);}RE;}TE IN VO IntervalMultiplyLazySqrtDecomposition::SolveSuspendedSubstitution(CRI d,CO U& u){CO int i_min = d * m_N_sqrt;IntervalSet_Body(i_min,i_min + m_N_sqrt,u);m_suspended[d]= false;RE;}TE IN VO IntervalMultiplyLazySqrtDecomposition::IntervalSet_Body(CRI i_min,CRI i_ulim,CO U& u){for(int i = i_min;i < i_ulim;i++){m_a[i]= u;}RE;}TE IN VO IntervalMultiplyLazySqrtDecomposition::SolveSuspendedAction(CRI d){CO int i_min = d * m_N_sqrt;CO int i_ulim = i_min + m_N_sqrt;R& m_lazy_action_d = m_lazy_action[d];if(m_lazy_action_d != m_L.Point()){IntervalAct_Body(i_min,i_ulim,m_lazy_action_d);m_lazy_action_d = m_L.Point();}CO U& one = m_M.One();U& m_lazy_MU_d = m_lazy_MU[d];if(m_lazy_MU_d != one){IntervalMultiply_Body(i_min,i_ulim,m_lazy_MU_d);m_lazy_MU_d = one;}RE;}TE IN VO IntervalMultiplyLazySqrtDecomposition::IntervalAct_Body(CRI i_min,CRI i_ulim,CO R& r){for(int i = i_min;i < i_ulim;i++){U& m_ai = m_a[i];m_ai = m_M.ScalarProduct(r,m_ai);}RE;}TE IN VO IntervalMultiplyLazySqrtDecomposition::IntervalMultiply_Body(CRI i_min,CRI i_ulim,CO U& u){for(int i = i_min;i < i_ulim;i++){U& m_ai = m_a[i];m_ai = m_M.Product(MO(m_ai),u);}RE;}TE IN U IntervalMultiplyLazySqrtDecomposition::IntervalProduct_Body(CRI i_min,CRI i_ulim){U AN = m_M.One();for(int i = i_min;i < i_ulim;i++){AN = m_M.Product(MO(AN),m_a[i]);}RE AN;}TE TE IN int IntervalMultiplyLazySqrtDecomposition::Search(CRI i_start,CO F& f,CO bool& reversed){RE reversed?SearchReverse_Body(i_start,f,m_M.One()):Search_Body(i_start,f,m_M.One());}TE IN int IntervalMultiplyLazySqrtDecomposition::Search(CRI i_start,CO U& u,CO bool& reversed){RE Search(i_start,[&](CO U& product,CRI){RE !(product < u);},reversed);}TE TE int IntervalMultiplyLazySqrtDecomposition::Search_Body(CRI i_start,CO F& f,U product_temp){CO int i_min = max(i_start,0);CO int d_0 = i_min / m_N_sqrt + 1;CO int i_0 = min(d_0 * m_N_sqrt,m_N);if(i_min < i_0){CO int d_0_minus = d_0 - 1;if(m_suspended[d_0_minus]){SolveSuspendedSubstitution(d_0_minus,m_lazy_substitution[d_0_minus]);}else{SolveSuspendedAction(d_0_minus);}}for(int i = i_min;i < i_0;i++){product_temp = m_M.Product(MO(product_temp),m_a[i]);if(f(product_temp,i)){RE i;}}for(int d = d_0;d < m_N_d;d++){U product_next = m_M.Product(product_temp,m_b[d]);if(f(product_next,min((d + 1)* m_N_sqrt,m_N)- 1)){RE Search_Body(d * m_N_sqrt,f,MO(product_temp));}product_temp = MO(product_next);}RE -1;}TE TE int IntervalMultiplyLazySqrtDecomposition::SearchReverse_Body(CRI i_final,CO F& f,U product_temp){CO int i_max = min(i_final,m_N - 1);CO int d_1 = i_max / m_N_sqrt;CO int i_1 = max(d_1 * m_N_sqrt,0);if(m_suspended[d_1]){SolveSuspendedSubstitution(d_1,m_lazy_substitution[d_1]);}else{SolveSuspendedAction(d_1);}for(int i = i_max;i >= i_1;i--){product_temp = m_M.Product(m_a[i],product_temp);if(f(product_temp,i)){RE i;}}for(int d = d_1 - 1;d >= 0;d--){U product_next = m_M.Product(m_b[d],product_temp);if(f(product_next,d * m_N_sqrt)){RE Search_Body((d + 1)* m_N_sqrt - 1,f,MO(product_temp));}product_temp = MO(product_next);}RE -1;} #endif #define PO Polynomial #define FPS FormalPowerSeries #ifdef DEBUG #include "c:/Users/user/Documents/Programming/Mathematics/Polynomial/FPS/a_Body.hpp" #else ST_AS( is_same_v> ); TE CE INT Log(INT N){INT AN = 0,pw = 1;WH(N > pw){pw <<= 1;AN++;}RE AN;} TE CL Power3Power_CE{PU:T m_val[EX_lim];CE Power3Power_CE(CO T& t);CE CO T& OP[](CRI i)CO;CE CO T(&Get()CO)[EX_lim];}; TE CE Power3Power_CE::Power3Power_CE(CO T& t):m_val(){T pw{t};for(uint EX = EX_lim - 1;EX + 1 > 0;EX--){m_val[EX]= -pw;m_val[EX]*= pw *= pw;}}TE CE CO T& Power3Power_CE::OP[](CRI i)CO{AS(i < EX_lim);RE m_val[i];}TE CE CO T(&Power3Power_CE::Get()CO)[EX_lim]{RE m_val;} #define DC_OF_AR_FOR_PO(FUNC)IN PO OP FUNC(PO f)CO;IN PO OP FUNC(T t)CO #define DF_OF_AR_FOR_PO(FUNC,DEF)TE IN PO PO::OP FUNC(PO f)CO{RE MO(DEF);};TE IN PO PO::OP FUNC(T t)CO{RE *TH FUNC PO(MO(t));} TE CL PO{PU:VE m_f;int m_SZ;IN PO();IN PO(CO PO& f);IN PO(PO&& f);IN PO(VE f);IN PO(T t);IN PO(CRI i,T t);IN PO& OP=(T n);IN PO& OP=(PO f);IN PO& OP=(VE f);IN CO T& OP[](CRI i)CO;IN T& OP[](CRI i);T OP()(CO T& t)CO;PO& OP+=(CO PO& f);PO& OP-=(CO PO& f);PO& OP*=(PO f);IN PO& OP/=(CO PO& f);PO& OP/=(CO T& t);PO& OP%=(CO PO& f);PO& OP%=(CO T& t);bool OP==(CO PO& f)CO;bool OP==(CO T& t)CO;TE IN bool OP!=(CO P& f)CO;DC_OF_AR_FOR_PO(+);IN PO OP-()CO;DC_OF_AR_FOR_PO(-);DC_OF_AR_FOR_PO(*);IN PO OP/(CO PO& f)CO;IN PO OP/(CO T& t)CO;IN PO OP%(CO PO& f)CO;IN PO OP%(CO T& t)CO;IN CO VE& GetCoefficient()CO NE;IN CRI SZ()CO NE;IN VO resize(CRI deg_plus)NE;int Valuation()CO NE;IN VO swap(PO& f);IN VO swap(VE& f);VO Reduce();VO TP(CRI N_trunc);ST PO NaiveCN(PO f0,CRI valuation0,CO PO& f1,CRI valuation1,CRI N_trunc);ST PO NaiveQuotient(PO f0,CO PO& f1);ST PO NaiveResidue(PO f0,CO PO& f1);ST IN CO PO& zero();ST IN CO PO& one();ST IN CO PO& x();ST IN CO T& c_zero();ST IN CO T& c_one();ST IN CO T& c_minus_one();IN PO& SignInvert();}; TE CL FPS:PU PO{PU:int m_N;IN FPS(CRI N = 0);IN FPS(CO FPS& f);IN FPS(FPS&& f);IN FPS(CRI N,T t);IN FPS(CRI N,CO PO& f);IN FPS(CRI N,PO&& f);IN FPS(CRI N,VE&& f);IN FPS(CRI N,CRI i,T t);IN FPS& OP=(FPS f);IN FPS& OP=(T n);IN FPS& OP=(PO f);IN FPS& OP+=(CO T& t);FPS& OP+=(CO PO& f);IN FPS& OP+=(CO FPS& f);IN FPS& OP-=(CO T& t);FPS& OP-=(CO PO& f);IN FPS& OP-=(CO FPS& f);IN FPS& OP*=(CO T& t);FPS& OP*=(PO f);IN FPS& OP*=(FPS f);IN FPS& OP/=(CO T& t);IN FPS& OP/=(CO FPS& t);TE IN FPS OP+(CO P& f)CO;IN FPS OP-()CO;TE IN FPS OP-(CO P& f)CO;TE IN FPS OP*(CO P& f)CO;TE IN FPS OP/(CO P& f)CO;FPS Inverse()CO;IN VO SetTruncation(CRI N)NE;IN CRI GetTruncation()CO NE;IN FPS& TruncateInitial(CRI N)NE;IN FPS& TruncateFinal(CRI N)NE;}; TE US FPS = FPS; #define PS_FOR_FFT_BODY(MOD,LE,PR,IPR,TYPE)ST_AS((TYPE::DeRP(PR)*= TYPE::DeRP(IPR))== TYPE::DeRP(1));TE <> CE CO uint LimitOfPowerForFFT = LE - 1;TE <> IN CO TYPE(&PrimitiveRootOfTwoForFFT()NE)[LimitOfPowerForFFT]{ST CE Power3Power_CE> PRT{PR};ST_AS(PRT.m_val[0]== TYPE::DeRP(1));RE PRT.Get();}TE <> IN CO TYPE(&InversePrimitiveRootOfTwoForFFT()NE)[LimitOfPowerForFFT]{ST CE Power3Power_CE> IPRT{IPR};ST_AS(IPRT.m_val[0]== TYPE::DeRP(1)&&(TYPE::DeRP(PR)*= TYPE::DeRP(IPR))== TYPE::DeRP(1));RE IPRT.Get();}TE <> IN PO& PO::OP*=(PO f){CO int SZ = m_SZ + f.m_SZ - 1;RE *TH = FFTCN(MO(*TH),MO(f),SZ);}TE <> IN PO& PO::OP/=(CO PO& f){AS(f.m_SZ > 0 && f[f.m_SZ-1]!= c_zero());Reduce();if(m_SZ < f.m_SZ){RE *TH = zero();}RE *TH = FFTQuotient(MO(*TH),f);}TE <> IN PO& PO::OP%=(CO PO& f){AS(f.m_SZ > 0 && f[f.m_SZ-1]!= c_zero());Reduce();RE *TH = FFTResidue(MO(*TH),f);} #define PS_FOR_FFT(MOD,LE,PR,IPR,MINT)PS_FOR_FFT_BODY(MOD,LE,PR,IPR,MINT) TE CE CO int LimitOfPowerForFFT;TE IN CO T(&PrimitiveRootOfTwoForFFT()NE)[LimitOfPowerForFFT];TE IN CO T(&InversePrimitiveRootOfTwoForFFT()NE)[LimitOfPowerForFFT]; TE VO CooleyTukey(VE& f,CRI N_shift,CRI N_input_start,CRI N_input_lim,CRI N_trunc,CRI two_pw,CRI EX,CO T(&PRT)[LimitOfPowerForFFT]){AS(N_input_lim - N_input_start <= two_pw);CO int N_zero = N_shift + N_input_start,le = N_zero + two_pw;AS(N_zero <= N_trunc);CO int N_input_final = min(N_input_start + two_pw,int(f.SZ()));for(int i = N_input_lim;i < N_input_final;i++){f[i]= T{};}WH(int(f.SZ())< le){f.push_back(T{});}ST VE bit_reverse[32]={VE(1)};ST int e_next = 1;ST int two_pw_next = 1;ST int two_pw_next2 = 2;ST VE* p_bit_reverse_prev = bit_reverse;ST VE* p_bit_reverse_curr = p_bit_reverse_prev + 1;WH(e_next <= EX){*p_bit_reverse_curr = VE(two_pw_next2);int* p_bit_reverse_curr_i = &((*p_bit_reverse_curr)[0]);int* p_bit_reverse_curr_i_plus = p_bit_reverse_curr_i + two_pw_next;int* p_bit_reverse_prev_i = &((*p_bit_reverse_prev)[0]);for(int i = 0;i < two_pw_next;i++){(*(p_bit_reverse_curr_i_plus++)= *(p_bit_reverse_curr_i++)= *(p_bit_reverse_prev_i++)* 2)+= 1;}e_next++;swap(two_pw_next,two_pw_next2);two_pw_next2 *= 4;p_bit_reverse_prev++;p_bit_reverse_curr++;}CO VE& bit_reverse_EX = bit_reverse[EX];int bit_num = 0;CO int* p_bit_num_reverse = &(bit_reverse_EX[bit_num]);WH(bit_num < two_pw){if(*p_bit_num_reverse < bit_num){swap(f[*p_bit_num_reverse + N_input_start],f[bit_num + N_input_start]);}bit_num++;p_bit_num_reverse++;}CO T& one = PRT[0];T zeta,diff;int i,j,j_lim,two_pw_curr = 1,two_pw_curr_2 = 2;WH(two_pw_curr < two_pw){CO int N_input_final_curr = N_input_start + two_pw_curr;bit_num = 0;i = 0;zeta = one;WH(i < two_pw){j = i;j_lim = i + two_pw_curr;WH(j < j_lim){diff = f[j + N_input_start]- f[j + N_input_final_curr];f[j + N_input_start]+= f[j + N_input_final_curr];f[j + N_input_final_curr]= zeta * diff;j++;}bit_num++;i += two_pw_curr_2;j = 0;WH(true){if(((bit_num >> j)& 1)== 1){zeta *= PRT[j+1];break;}j++;}}two_pw_curr <<= 1;two_pw_curr_2 <<= 1;}if(N_trunc < le){f.resize(N_trunc);}if(N_shift > 0){for(int i = N_trunc - 1;i >= N_zero;i--){f[i]= MO(f[i - N_shift]);}for(int i = N_zero - 1;i >= N_input_start;i--){f[i]= T{};}}RE;}TE IN VO FFT(VE& f,CRI N_input_start,CRI N_input_lim,CRI two_pw,CRI EX){CooleyTukey(f,0,N_input_start,N_input_lim,N_input_start + two_pw,two_pw,EX,PrimitiveRootOfTwoForFFT());}TE IN VO IFFT(VE& f,CRI N_shift,CRI N_input_start,CRI N_input_lim,CRI N_trunc,CRI two_pw,CO T& two_pw_inv,CRI EX){CooleyTukey(f,N_shift,N_input_start,N_input_lim,N_trunc,two_pw,EX,InversePrimitiveRootOfTwoForFFT());CO int SZ = f.SZ();for(int i = N_shift + N_input_start;i < SZ;i++){f[i]*= two_pw_inv;}}TE PO FFTCN(PO f0,PO f1,CRI N_trunc){f0.Reduce();if(f0.m_SZ == 0){RE MO(f0);}f1.Reduce();if(f1.m_SZ == 0){RE MO(f1);}AS(f0.m_SZ <= N_trunc);CO int valuation0 = f0.Valuation();CO int valuation1 = f1.Valuation();if(N_trunc <= valuation0 + valuation1){RE f0.zero();}CO int le0 = f0.m_SZ - valuation0;CO int le1 = min(f1.m_SZ,N_trunc)- valuation1;CO int le = le0 + le1 - 1;CO int EX = Log(le);if(min(le0,le1)<= EX){RE f0.NaiveCN(MO(f0),valuation0,MO(f1),valuation1,min(f0.m_SZ + f1.m_SZ - 1,N_trunc));}CO int two_pw = 1 << EX;FFT(f0.m_f,valuation0,f0.m_SZ,two_pw,EX);FFT(f1.m_f,valuation1,valuation1 + le1,two_pw,EX);for(int i = 0;i < two_pw;i++){f0.m_f[i + valuation0]*= f1.m_f[i + valuation1];}IFFT(f0.m_f,valuation1,valuation0,valuation0 + two_pw,N_trunc,two_pw,f0.c_one()/ two_pw,EX);f0.m_SZ = f0.m_f.SZ();RE MO(f0);}TE PO FFTQuotient(PO f0,PO f1){AS(f1.m_SZ > 0 && f1[f1.m_SZ-1]!= f0.c_zero());if(f0.m_SZ < f1.m_SZ){RE PO::zero();}CO int f0_TP_SZ = f0.m_SZ - f1.m_SZ + 1;CO int f1_TP_SZ = min(f0_TP_SZ,f1.m_SZ);f1.TP(f1_TP_SZ);CO FPS f1_TP_inverse = FPS(f0_TP_SZ,MO(f1)).Inverse();f0.TP(f0_TP_SZ);FPS f0_TP{f0_TP_SZ,MO(f0)};f0_TP *= f1_TP_inverse;f0_TP.TP(f0_TP_SZ);RE f0_TP;}TE PO FFTResidue(PO f0,CO PO& f1){if(f0.m_SZ >= f1.m_SZ){f0 -=(f0 / f1)* f1;f0.Reduce();}RE MO(f0);} PS_FOR_FFT(P,24,31,128805723,Mod); PS_FOR_FFT(167772161,26,17,29606852,Mod); PS_FOR_FFT(469762049,27,30,15658735,Mod); PS_FOR_FFT(754974721,25,362,415027540,Mod); TE IN FPS::FPS(CRI N):PO(),m_N(N){AS(m_N > 0);}TE IN FPS::FPS(CO FPS& f):PO(f),m_N(f.m_N){}TE IN FPS::FPS(FPS&& f):PO(MO(f.m_f)),m_N(f.m_N){}TE IN FPS::FPS(CRI N,T t):PO(MO(t)),m_N(N){AS(m_N > 0);}TE IN FPS::FPS(CRI N,CO PO& f):PO(),m_N(N){AS(m_N > 0);TH->m_SZ = f.m_SZ < m_N?f.m_SZ:m_N;TH->m_f = VE(TH->m_SZ);for(int i = 0;i < TH->m_SZ;i++){TH->m_f[i]= f.m_f[i];}}TE IN FPS::FPS(CRI N,PO&& f):PO(),m_N(N){if(f.m_SZ < m_N * 2){PO::OP=(MO(f));if(f.m_SZ > m_N){TruncateFinal(m_N);}}else{TH->m_f = VE(m_N);for(int i = 0;i < m_N;i++){TH->m_f[i]= MO(f.m_f[i]);}TH->m_SZ = m_N;}}TE IN FPS::FPS(CRI N,VE&& f):PO(),m_N(N){AS(m_N > 0);CO int f_SZ = f.SZ();if(f_SZ < m_N * 2){PO::OP=(MO(f));if(f_SZ > m_N){TruncateFinal(m_N);}}else{TH->m_f = VE(m_N);for(int i = 0;i < m_N;i++){TH->m_f[i]= MO(f[i]);}}}TE IN FPS::FPS(CRI N,CRI i,T t):PO(),m_N(N){AS(m_N > 0);if(i < m_N?t != TH->c_zero():false){(*TH)[i]= MO(t);}}TE IN FPS& FPS::OP=(FPS f){PO::OP=(MO(f.m_f));m_N = f.m_N;RE *TH;}TE IN FPS& FPS::OP=(T n){PO::OP=(MO(n));RE *TH;}TE IN FPS& FPS::OP=(PO f){RE OP=(FPS(m_N,MO(f)));}TE IN FPS& FPS::OP+=(CO T& t){PO::OP+=(t);RE *TH;}TE FPS& FPS::OP+=(CO PO& f){CRI SZ_f = m_N < f.m_SZ?m_N:f.m_SZ;CRI SZ = TH->m_SZ < SZ_f?TH->m_SZ:SZ_f;for(int i = 0;i < SZ;i++){TH->m_f[i]+= f.m_f[i];}for(int i = SZ;i < SZ_f;i++){TH->m_f.push_back(f.m_f[i]);}TH->m_SZ = TH->m_f.SZ();RE *TH;}TE IN FPS& FPS::OP+=(CO FPS& f){AS(m_N <= f.m_N);CO PO& f_ref = f;RE OP+=(f_ref);}TE IN FPS& FPS::OP-=(CO T& t){PO::OP-=(t);RE *TH;}TE FPS& FPS::OP-=(CO PO& f){CRI SZ_f = m_N < f.m_SZ?m_N:f.m_SZ;CRI SZ = TH->m_SZ < SZ_f?TH->m_SZ:SZ_f;for(int i = 0;i < SZ;i++){TH->m_f[i]-= f.m_f[i];}for(int i = SZ;i < SZ_f;i++){TH->m_f.push_back(-f.m_f[i]);}TH->m_SZ = TH->m_f.SZ();RE *TH;}TE IN FPS& FPS::OP-=(CO FPS& f){AS(m_N <= f.m_N);CO PO& f_ref = f;RE OP-=(f_ref);}TE IN FPS& FPS::OP*=(CO T& t){PO::OP*=(t);RE *TH;}TE FPS& FPS::OP*=(PO f){*TH = FFTCN(forward>(*TH),MO(f),m_N);RE *TH;}TE IN FPS& FPS::OP*=(FPS f){AS(m_N <= f.m_N);RE OP*=(forward>(f));}TE IN FPS& FPS::OP/=(CO T& t){PO::OP/=(t);RE *TH;}TE IN FPS& FPS::OP/=(CO FPS& f){AS(m_N <= f.m_N);RE OP*=(m_N == f.m_N?f.Inverse():FPS(m_N,f).Inverse());}TE TE IN FPS FPS::OP+(CO P& f)CO{RE MO(FPS(*TH)+= f);}TE IN FPS FPS::OP-()CO{RE MO(FPS(m_N)-= *TH);}TE TE IN FPS FPS::OP-(CO P& f)CO{RE MO(FPS(*TH)-= f);}TE TE IN FPS FPS::OP*(CO P& f)CO{RE MO(FPS(*TH)*= f);}TE TE IN FPS FPS::OP/(CO P& f)CO{RE MO(FPS(*TH)/= f);}TE FPS FPS::Inverse()CO{AS(TH->m_SZ > 0 && TH->m_f[0]!= TH->c_zero());CO PO& TH_ref = *TH;int pw;int pw_2 = 1;FPS f_inv{pw_2,TH->c_one()/ TH->m_f[0]};WH(pw_2 < m_N){pw = pw_2;pw_2 <<= 1;f_inv.SetTruncation(pw_2);auto temp = f_inv * TH_ref;temp[0]--;temp *= f_inv;for(int i = pw;i < pw_2;i++){f_inv[i]-= temp[i];}}f_inv.SetTruncation(m_N);RE f_inv;}TE IN VO FPS::SetTruncation(CRI N)NE{if(N < m_N){TruncateFinal(N);}m_N = N;}TE IN CRI FPS::GetTruncation()CO NE{RE m_N;}TE IN FPS& FPS::TruncateInitial(CRI N)NE{CRI SZ = N < TH->m_SZ?N:TH->m_SZ;for(int i = 0;i < SZ;i++){TH->m_f[i]= 0;}RE *TH;}TE IN FPS& FPS::TruncateFinal(CRI N)NE{WH(TH->m_SZ > N){TH->m_f.pop_back();TH->m_SZ--;}RE *TH;}TE FPS Differential(CO FPS& f){auto& SZ = f.SZ();auto& N = f.GetTruncation();if(SZ < 1){RE FPS(1 < N?N - 1:1);}VE df(SZ - 1);for(int i = 1;i < SZ;i++){df[i - 1]= f[i]* i;}RE FPS(1 < N?N - 1:1,MO(df));}TE FPS Differential(CRI n,CO FPS& f){if(n == 0){RE f;}if(n == 1){RE Differential(f);}auto& SZ = f.SZ();auto& N = f.GetTruncation();if(SZ < n){RE FPS(n < N?N - n:1);}VE df(SZ - n);T coef = T::Factorial(n),numer = n,denom = 0;for(int i = n;i < SZ;i++){df[i - n]= f[i]* coef;(coef *= ++numer)/= ++denom;}RE FPS(n < N?N - n:1,MO(df));}TE FPS ShiftedIntegral(CRI n,CO FPS& f,CRI shift){auto& SZ = f.SZ();auto& N = f.GetTruncation();if(SZ + n < shift){RE FPS{N + n > shift?N + n - shift:1};}VE F(SZ + n - shift);if(n == 0){for(int i = shift;i < SZ;i++){F[i - shift]= f[i];}}else if(n == 1){CO int i_min = max(shift - 1,0);T denom = i_min;for(int i = i_min;i < SZ;i++){F[i + 1 - shift]= f[i]/ ++denom;}}else{CO int i_min = max(shift - n,0);for(int i = i_min;i < SZ;i++){F[i + n - shift]= f[i]* T::Factorial(i)* T::FactorialInverse(n + i);}}RE FPS(N + n - shift,MO(F));}TE IN FPS Integral(CO FPS& f){RE ShiftedIntegral(1,f,0);}TE IN FPS Integral(CRI n,CO FPS& f){RE ShiftedIntegral(n,f,0);}TE FPS Exp(CO FPS& f){AS(f[0]== f.c_zero());CRI N = f.GetTruncation();int pw;int pw_2 = 1;FPS f_exp{pw_2,f.c_one()};WH(pw_2 < N){pw = pw_2;pw_2 *= 2;f_exp.SetTruncation(pw_2);auto temp = Differential(f_exp);temp /= f_exp;temp = ShiftedIntegral(1,temp,pw);for(int i = 0;i < pw;i++){temp[i]-= f[i | pw];}temp *= f_exp;for(int i = 0;i < pw;i++){f_exp[i|pw]-= temp[i];}}f_exp.SetTruncation(N);RE f_exp;}TE IN FPS Log(CO FPS& f){AS(f[0]== f.c_one());RE Integral(Differential(f)/= f);}TE IN OS& OP<<(OS& os,CO FPS& f){CO int N = f.GetTruncation();for(int i = 0;i < N;i++){(i > 0?os << " ":os)<< f[i];}RE os;} TE IN PO::PO():m_f(),m_SZ(0){}TE IN PO::PO(CO PO& f):m_f(f.m_f),m_SZ(f.m_SZ){}TE IN PO::PO(PO&& f):m_f(MO(f.m_f)),m_SZ(f.m_SZ){}TE IN PO::PO(VE f):m_f(MO(f)),m_SZ(m_f.SZ()){}TE IN PO::PO(T t):PO(){if(t != c_zero()){OP[](0)= MO(t);}}TE IN PO::PO(CRI i,T t):PO(){if(t != c_zero()){OP[](i)= MO(t);}}TE IN PO& PO::OP=(T n){m_f.clear();m_SZ = 0;OP[](0)= MO(n);RE *TH;}TE IN PO& PO::OP=(PO f){m_f = MO(f.m_f);m_SZ = f.m_SZ;RE *TH;}TE IN PO& PO::OP=(VE f){m_f = MO(f);m_SZ = m_f.SZ();RE *TH;}TE IN CO T& PO::OP[](CRI i)CO{RE m_SZ <= i?c_zero():m_f[i];}TE IN T& PO::OP[](CRI i){if(m_SZ <= i){CO T& z = c_zero();WH(m_SZ <= i){m_f.push_back(z);m_SZ++;}}RE m_f[i];}TE T PO::OP()(CO T& t)CO{T AN =(*TH)[0];T t_pw = c_one();for(int d = 1;d < m_SZ;d++){AN += m_f[d]*(t_pw *= t);}RE AN;}TE PO& PO::OP+=(CO PO& f){if(m_SZ < f.m_SZ){for(int i = 0;i < m_SZ;i++){m_f[i]+= f.m_f[i];}for(int i = m_SZ;i < f.m_SZ;i++){m_f.push_back(f.m_f[i]);}m_SZ = f.m_SZ;}else{for(int i = 0;i < f.m_SZ;i++){m_f[i]+= f.m_f[i];}}RE *TH;}TE PO& PO::OP-=(CO PO& f){if(m_SZ < f.m_SZ){for(int i = 0;i < m_SZ;i++){m_f[i]-= f.m_f[i];}for(int i = m_SZ;i < f.m_SZ;i++){m_f.push_back(- f.m_f[i]);}m_SZ = f.m_SZ;}else{for(int i = 0;i < f.m_SZ;i++){m_f[i]-= f.m_f[i];}}RE *TH;}TE PO& PO::OP/=(CO T& t){if(t == c_one()){RE *TH;}CO T t_inv{c_one()/ t};for(int i = 0;i < m_SZ;i++){OP[](i)*= t_inv;}RE *TH;}TE PO& PO::OP%=(CO T& t){if(t == c_one()){RE *TH = zero();}for(int i = 0;i < m_SZ;i++){m_f[i]%= t;}RE *TH;}TE bool PO::OP==(CO PO& f)CO{CRI SZ0 = SZ();CRI SZ1 = f.SZ();CRI SZ_max = SZ0 < SZ1?SZ1:SZ0;for(int i = 0;i < SZ_max;i++){if(OP[](i)!= f[i]){RE false;}}RE true;}TE bool PO::OP==(CO T& t)CO{CRI SZ_max = SZ();CO T& zero = PO::c_zero();for(int i = 1;i < SZ_max;i++){if(m_f[i]!= zero){RE false;}}RE OP[](0)== t;}TE TE IN bool PO::OP!=(CO P& f)CO{RE !(*TH == f);}DF_OF_AR_FOR_PO(+,f += *TH);TE IN PO& PO::SignInvert(){Reduce();for(auto& fi:m_f){fi = -fi;}RE *TH;}TE IN PO PO::OP-()CO{RE MO(PO(*TH).SignInvert());}DF_OF_AR_FOR_PO(-,f.SignInvert()+= *TH);DF_OF_AR_FOR_PO(*,f *= *TH);TE IN PO PO::OP/(CO T& t)CO{RE MO(PO(*TH)/= t);}TE IN PO PO::OP/(CO PO& f)CO{RE MO(PO(*TH)/= f);}TE IN PO PO::OP%(CO T& t)CO{RE MO(PO(*TH)%= t);}TE IN PO PO::OP%(CO PO& f)CO{RE MO(PO(*TH)%= f);}TE IN CO VE& PO::GetCoefficient()CO NE{RE m_f;}TE IN CRI PO::SZ()CO NE{RE m_SZ;}TE IN VO PO::resize(CRI deg_plus)NE{m_f.resize(m_SZ = deg_plus);}TE int PO::Valuation()CO NE{for(int i = 0;i < m_SZ;i++){if(m_f[i]!= c_zero()){RE i;}}RE -1;}TE IN VO PO::swap(PO& f){m_f.swap(f.m_f);swap(m_SZ,f.m_SZ);}TE IN VO PO::swap(VE& f){m_f.swap(f);m_SZ = m_f.SZ();}TE VO PO::Reduce(){CO T& z = c_zero();WH(m_SZ > 0 && m_f[m_SZ - 1]== z){m_f.pop_back();m_SZ--;}RE;}TE VO PO::TP(CRI N_trunc){WH(N_trunc > m_SZ){m_f.push_back(c_zero());m_SZ++;}CO int N_half = min(N_trunc,(m_SZ + 1)/ 2);for(int d = 0;d < N_half;d++){::swap(m_f[d],m_f[m_SZ - 1 - d]);}m_f.resize(N_trunc);m_SZ = N_trunc;RE;}TE IN CO PO& PO::zero(){ST CO PO z{};RE z;}TE IN CO PO& PO::one(){ST CO PO o{c_one()};RE o;}TE IN CO PO& PO::x(){ST CO PO f{1,c_one()};RE f;}TE IN CO T& PO::c_zero(){ST CO T z{0};RE z;}TE IN CO T& PO::c_one(){ST CO T o{1};RE o;}TE IN CO T& PO::c_minus_one(){ST CO T m{-1};RE m;}TE PO Differential(CRI n,CO PO& f){CRI SZ = f.SZ();if(SZ < n){RE PO::zero();}VE df(SZ - n);T coef = T::Factorial(n);int i = n;WH(i < SZ){df[i - n]= f[i]* coef;i++;(coef *= i)/=(i - n);}RE PO(MO(df));}TE IN PO Differential(CO PO& f){RE Differential(1,f);} TE PO PO::NaiveCN(PO f0,CRI valuation0,CO PO& f1,CRI valuation1,CRI N_trunc){CO int SZ0 = f0.SZ();AS(0 <= valuation0 && valuation0 < SZ0);CO int SZ1 = f1.SZ();AS(0 <= valuation1 && valuation1 < SZ1);for(int i = SZ0 - 1;i >= valuation0;i--){CO T f0i = f0[i];f0[i]*= f1[0];CO int j_ulim = min(SZ1,N_trunc - i),j_min = max(valuation1,1);for(int j = j_ulim - 1;j >= j_min;j--){f0[i+j]+= f0i * f1[j];}}RE MO(f0);}TE IN OS& OP<<(OS& os,CO PO& f){auto& SZ = f.SZ();for(int i = 0;i < SZ;i++){(i == 0?os:os << " ")<< f[i];}RE os;} TE PO PO::NaiveQuotient(PO f0,CO PO& f1){CO int diff = f0.m_SZ - f1.m_SZ;if(diff < 0){RE MO(f0);}CO T r = f0[f0.m_SZ-1]/ f1[f1.m_SZ-1];f0.m_f.pop_back();f0.m_SZ--;f0.Reduce();for(int i = diff;i < f0.m_SZ;i++){f0[i]-= r * f1[i - diff];}f0.Reduce();f0 = NaiveQuotient(MO(f0),f1);f0[diff]= r;RE MO(f0);}TE PO PO::NaiveResidue(PO f0,CO PO& f1){CO int diff = f0.m_SZ - f1.m_SZ;if(diff < 0){RE MO(f0);}CO T r = f0[f0.m_SZ-1]/ f1[f1.m_SZ-1];f0.m_f.pop_back();f0.m_SZ--;f0.Reduce();for(int i = diff;i < f0.m_SZ;i++){f0[i]-= r * f1[i - diff];}f0.Reduce();RE NaiveResidue(MO(f0),f1);}TE PO& PO::OP*=(PO f){Reduce();if(m_SZ == 0){RE *TH;}f.Reduce();if(f.m_SZ == 0){RE *TH = MO(f);}CO int valuation0 = TH->Valuation();CO int valuation1 = f.Valuation();CO int le0 = m_SZ - valuation0;CO int le1 = f.m_SZ - valuation1;CO int SZ = m_SZ + f.m_SZ - 1;m_f = NaiveCN(MO(*TH),valuation0,f,valuation1,SZ);m_SZ = m_f.SZ();RE *TH;}TE PO& PO::OP/=(CO PO& f){AS(f.m_SZ > 0 && f[f.m_SZ-1]!= c_zero());Reduce();if(m_SZ < f.m_SZ){RE *TH = zero();}RE *TH = NaiveQuotient(MO(*TH),f);}TE PO& PO::OP%=(CO PO& f){AS(f.m_SZ > 0 && f[f.m_SZ-1]!= c_zero());Reduce();RE *TH = NaiveResidue(MO(*TH),f);} #endif /* AAA 常設でないライブラリは以上に挿入する。*/ #define INCLUDE_SUB #include __FILE__ #else /* INCLUDE_LIBRARY */ #ifdef DEBUG #define _GLIBCXX_DEBUG #else #pragma GCC optimize ( "O3" ) #pragma GCC optimize ( "unroll-loops" ) #pragma GCC target ( "sse4.2,fma,avx2,popcnt,lzcnt,bmi2" ) #define DEXPR( LL , BOUND , VALUE1 , VALUE2 ) CEXPR( LL , BOUND , VALUE1 ) #define ASSERT( A , MIN , MAX ) AS( ( MIN ) <= A && A <= ( MAX ) ) #define REPEAT_MAIN( BOUND ) START_MAIN; CEXPR( int , test_case_num_bound , BOUND ); int test_case_num = 1; if CE( test_case_num_bound > 1 ){ FINISH_MAIN #ifdef USE_GETLINE #else #define SET( ... ) VariadicCin( cin , __VA_ARGS__ ) #define CIN( LL , ... ) LL __VA_ARGS__; SET( __VA_ARGS__ ) #define SET_A( I , N , ... ) VariadicResize( N + I , __VA_ARGS__ ); FOR( VARIABLE_FOR_SET_A , 0 , N ){ VariadicSet( cin , VARIABLE_FOR_SET_A + I , __VA_ARGS__ ); } #define CIN_A( LL , I , N , ... ) VE __VA_ARGS__; SET_A( I , N , __VA_ARGS__ ) #define CIN_AA( LL , I0 , N0 , I1 , N1 , VAR ) VE VAR( N0 + I0 , VE( N1 + I1 ) ); FOR( VARIABLE_FOR_CIN_AA , 0 , N0 ){ SET_A( I1 , N1 , VAR[VARIABLE_FOR_CIN_AA + I0] ); } #define FINISH_MAIN SET_ASSERT( test_case_num , 1 , test_case_num_bound ); } REPEAT( test_case_num ){ Solve(); } } #endif #define SET_ASSERT( A , MIN , MAX ) SET( A ); ASSERT( A , MIN , MAX ) #define SOLVE_ONLY #define COUT( ... ) VariadicCout( cout , __VA_ARGS__ ) << ENDL #define COUTNS( ... ) VariadicCoutNonSep( cout , __VA_ARGS__ ) #define CERR( ... ) #define CERRNS( ... ) #define COUT_A( I , N , A ) CoutArray( cout , I , N , A ) << ENDL #define CERR_A( I , N , A ) #define WHAT( ... ) #define TLE( CONDITION ) if( !( CONDITION ) ){ ll TLE_VAR = 1; while( TLE_VAR != 0 ){ ( TLE_VAR += 2 ) %= int( 1e9 ); } cerr << TLE_VAR << endl; } #define MLE( CONDITION ) if( !( CONDITION ) ){ vector> MLE_VAR{}; REPEAT( 1e6 ){ MLE_VAR.push_back( vector( 1e6 ) ); } cerr << MLE_VAR << endl; } #define OLE( CONDITION ) if( !( CONDITION ) ){ REPEAT( 1e8 ){ cerr << "OLE\n"; } } #endif #ifdef REACTIVE #else #define ENDL "\n" #endif #include using namespace std; #define ATT __attribute__( ( target( "sse4.2,fma,avx2,popcnt,lzcnt,bmi2" ) ) ) #define START_MAIN int main(){ ios_base::sync_with_stdio( false ); cin.tie( nullptr ) #define START_WATCH chrono::system_clock::time_point watch = chrono::system_clock::now(); double loop_average_time = 0.0 , loop_start_time = loop_average_time , current_time = loop_start_time; int loop_count = current_time; assert( loop_count == 0 ) #define CURRENT_TIME ( current_time = static_cast( chrono::duration_cast( chrono::system_clock::now() - watch ).count() / 1000.0 ) ) #define CHECK_WATCH( TL_MS ) ( CURRENT_TIME , loop_count == 0 ? loop_start_time = current_time : loop_average_time = ( current_time - loop_start_time ) / loop_count , ++loop_count , current_time < TL_MS - loop_average_time * 2 - 100.0 ) #define CEXPR( LL , BOUND , VALUE ) CE LL BOUND = VALUE #define SET_A_ASSERT( I , N , A , MIN , MAX ) FOR( VARIABLE_FOR_SET_A , 0 , N ){ SET_ASSERT( A[VARIABLE_FOR_SET_A + I] , MIN , MAX ); } #define SET_AA_ASSERT( I0 , N0 , I1 , N1 , A , MIN , MAX ) FOR( VARIABLE_FOR_SET_AA0 , 0 , N0 ){ FOR( VARIABLE_FOR_SET_AA1 , 0 , N1 ){ SET_ASSERT( A[VARIABLE_FOR_SET_AA0 + I0][VARIABLE_FOR_SET_AA1 + I1] , MIN , MAX ); } } #define CIN_ASSERT( A , MIN , MAX ) decldecay_t( MAX ) A; SET_ASSERT( A , MIN , MAX ) #define CIN_A_ASSERT( I , N , A , MIN , MAX ) vector A( N + I ); SET_A_ASSERT( I , N , A , MIN , MAX ) #define CIN_AA_ASSERT( I0 , N0 , I1 , N1 , A , MIN , MAX ) vector A( N0 + I0 , vector( N1 + I1 ) ); SET_AA_ASSERT( I0 , N0 , I1 , N1 , A , MIN , MAX ) #define PR1( A1 , ... ) A1 #define PR2( A1 , A2 , ... ) A2 #define PR3( A1 , A2 , A3 , ... ) A3 #define FOR_( VAR , INITIAL , FINAL , UPPER , COMP , INCR ) for( decldecay_t( UPPER ) VAR = INITIAL ; VAR COMP ( FINAL ) ; VAR INCR ) #define FOR( VAR , INITIAL , ... ) FOR_( VAR , INITIAL , PR1( __VA_ARGS__ ) , PR1( __VA_ARGS__ ) , < , PR3( __VA_ARGS__ , += PR2( __VA_ARGS__ , ? ) , ++ ) ) #define FOREQ( VAR , INITIAL , ... ) FOR_( VAR , INITIAL , PR1( __VA_ARGS__ ) , PR1( __VA_ARGS__ ) , <= , PR3( __VA_ARGS__ , += PR2( __VA_ARGS__ , ? ) , ++ ) ) #define FOREQINV( VAR , INITIAL , ... ) FOR_( VAR , INITIAL , PR1( __VA_ARGS__ ) , INITIAL , + 1 > , PR3( __VA_ARGS__ , -= PR2( __VA_ARGS__ , ? ) , -- ) ) #define ITR( ARRAY ) auto begin_ ## ARRAY = ARRAY .BE() , itr_ ## ARRAY = begin_ ## ARRAY , end_ ## ARRAY = ARRAY .EN() #define FOR_ITR( ARRAY ) for( ITR( ARRAY ) , itr = itr_ ## ARRAY ; itr_ ## ARRAY != end_ ## ARRAY ; itr_ ## ARRAY ++ , itr++ ) #define RUN( ARRAY , ... ) for( auto&& __VA_ARGS__ : ARRAY ) #define REPEAT( HOW_MANY_TIMES ) FOR( VARIABLE_FOR_REPEAT , 0 , HOW_MANY_TIMES ) #define SET_PRECISION( DECIMAL_DIGITS ) cout << fixed << setprecision( DECIMAL_DIGITS ); cerr << fixed << setprecision( DECIMAL_DIGITS ) #define RETURN( ... ) SOLVE_ONLY; COUT( __VA_ARGS__ ); RE #define COMPARE( ... ) auto naive = Naive( __VA_ARGS__ , false ); auto answer = Answer( __VA_ARGS__ , false ); bool match = naive == answer; CERR( "(" , #__VA_ARGS__ , ") == (" , __VA_ARGS__ , ") : Naive ==" , naive , match ? "==" : "!=" , answer , "== Answer" ); if( !match ){ CERR( "出力の不一致が検出されました。" ); RE; } #define CHECK( ... ) auto answer = Answer( __VA_ARGS__ , false ); CERR( "(" , #__VA_ARGS__ , ") == (" , __VA_ARGS__ , ") : Answer == " , answer ) /* 圧縮用 */ #define TE template #define TY typename #define US using #define ST static #define AS assert #define IN inline #define CL class #define PU public #define OP operator #define CE constexpr #define CO const #define NE noexcept #define RE return #define WH while #define VO void #define VE vector #define LI list #define BE begin #define EN end #define SZ size #define LE length #define PW Power #define MO move #define TH this #define CRI CO int& #define CRUI CO uint& #define CRL CO ll& #define VI virtual #define IS basic_istream #define OS basic_ostream #define ST_AS static_assert #define reMO_CO remove_const #define is_COructible_v is_constructible_v #define rBE rbegin /* 型のエイリアス */ #define decldecay_t(VAR)decay_t TE US ret_t = decltype(declval()(declval()...)); TE US inner_t = TY T::type; US uint = unsigned int; US ll = long long; US ull = unsigned long long; US ld = long double; US lld = __float128; /* VVV 常設ライブラリは以下に挿入する。*/ #ifdef DEBUG #include "C:/Users/user/Documents/Programming/Contest/Template/Local/a_Body.hpp" US MP = Mod

; #else /* Set (2KB)*/ CL is_ordered{PU:is_ordered()= delete;TE ST CE auto Check(CO T& t)-> decltype(t < t,true_type());ST CE false_type Check(...);TE ST CE CO bool value = is_same_v< decltype(Check(declval())),true_type >;}; TE US Set = conditional_t>,unordered_set,conditional_t,set,VO>>; /* Vector (3KB)*/ #define DF_OF_COUT_FOR_VE(V)TE IN OS& OP<<(OS& os,CO V& arg){auto BE = arg.BE(),EN = arg.EN();auto IT = BE;WH(IT != EN){(IT == BE?os:os << " ")<< *IT;IT++;}RE os;} DF_OF_COUT_FOR_VE(VE);DF_OF_COUT_FOR_VE(LI);DF_OF_COUT_FOR_VE(set);DF_OF_COUT_FOR_VE(unordered_set);DF_OF_COUT_FOR_VE(multiset);IN VO VariadicResize(CRI SZ){}TE IN VO VariadicResize(CRI SZ,Arg& arg,ARGS&... args){arg.resize(SZ);VariadicResize(SZ,args...);} /* Map (1KB)*/ TE US Map = conditional_t>,unordered_map,conditional_t,map,VO>>; /* StdStream (2KB)*/ TE IN IS& VariadicCin(IS& is){RE is;}TE IN IS& VariadicCin(IS& is,Arg& arg,ARGS&... args){RE VariadicCin(is >> arg,args...);}TE IN IS& VariadicSet(IS& is,CRI i){RE is;}TE IN IS& VariadicSet(IS& is,CRI i,Arg& arg,ARGS&... args){RE VariadicSet(is >> arg[i],i,args...);}TE IN OS& VariadicCout(OS& os,Arg&& arg){RE os << forward(arg);}TE IN OS& VariadicCout(OS& os,Arg1&& arg1,Arg2&& arg2,ARGS&&... args){RE VariadicCout(os << forward(arg1)<< " ",forward(arg2),forward(args)...);} /* Module (6KB)*/ #define DC_OF_CPOINT(POINT)IN CO U& POINT()CO NE #define DC_OF_POINT(POINT)IN U& POINT()NE #define DF_OF_CPOINT(POINT)TE IN CO U& VirtualPointedSet::POINT()CO NE{RE Point();} #define DF_OF_POINT(POINT)TE IN U& VirtualPointedSet::POINT()NE{RE Point();} TE CL UnderlyingSet{PU:US type = U;};TE CL VirtualPointedSet:VI PU UnderlyingSet{PU:VI CO U& Point()CO NE = 0;VI U& Point()NE = 0;DC_OF_CPOINT(Unit);DC_OF_CPOINT(Zero);DC_OF_CPOINT(One);DC_OF_CPOINT(Infty);DC_OF_POINT(init);DC_OF_POINT(root);};TE CL PointedSet:VI PU VirtualPointedSet{PU:U m_b_U;IN PointedSet(U b_u = U());IN CO U& Point()CO NE;IN U& Point()NE;};TE CL VirtualNSet:VI PU UnderlyingSet{PU:VI U Transfer(CO U& u)= 0;IN U Inverse(CO U& u);};TE CL AbstractNSet:VI PU VirtualNSet{PU:F_U m_f_U;IN AbstractNSet(F_U f_U);IN AbstractNSet& OP=(CO AbstractNSet&)NE;IN U Transfer(CO U& u);};TE CL VirtualMagma:VI PU UnderlyingSet{PU:VI U Product(U u0,CO U& u1)= 0;IN U Sum(U u0,CO U& u1);};TE CL AdditiveMagma:VI PU VirtualMagma{PU:IN U Product(U u0,CO U& u1);};TE CL MultiplicativeMagma:VI PU VirtualMagma{PU:IN U Product(U u0,CO U& u1);};TE CL AbstractMagma:VI PU VirtualMagma{PU:M_U m_m_U;IN AbstractMagma(M_U m_U);IN AbstractMagma& OP=(CO AbstractMagma&)NE;IN U Product(U u0,CO U& u1);}; TE IN PointedSet::PointedSet(U b_U):m_b_U(MO(b_U)){}TE IN CO U& PointedSet::Point()CO NE{RE m_b_U;}TE IN U& PointedSet::Point()NE{RE m_b_U;}DF_OF_CPOINT(Unit);DF_OF_CPOINT(Zero);DF_OF_CPOINT(One);DF_OF_CPOINT(Infty);DF_OF_POINT(init);DF_OF_POINT(root);TE IN AbstractNSet::AbstractNSet(F_U f_U):m_f_U(MO(f_U)){ST_AS(is_invocable_r_v);}TE IN AbstractNSet& AbstractNSet::operator=(CO AbstractNSet&)NE{RE *TH;}TE IN U AbstractNSet::Transfer(CO U& u){RE m_f_U(u);}TE IN U VirtualNSet::Inverse(CO U& u){RE Transfer(u);}TE IN AbstractMagma::AbstractMagma(M_U m_U):m_m_U(MO(m_U)){ST_AS(is_invocable_r_v);}TE IN AbstractMagma& AbstractMagma::OP=(CO AbstractMagma&)NE{RE *TH;}TE IN U AdditiveMagma::Product(U u0,CO U& u1){RE MO(u0 += u1);}TE IN U MultiplicativeMagma::Product(U u0,CO U& u1){RE MO(u0 *= u1);}TE IN U AbstractMagma::Product(U u0,CO U& u1){RE m_m_U(MO(u0),u1);}TE IN U VirtualMagma::Sum(U u0,CO U& u1){RE Product(MO(u0),u1);} TE CL VirtualMonoid:VI PU VirtualMagma,VI PU VirtualPointedSet{};TE CL AdditiveMonoid:VI PU VirtualMonoid,PU AdditiveMagma,PU PointedSet{};TE CL MultiplicativeMonoid:VI PU VirtualMonoid,PU MultiplicativeMagma,PU PointedSet{PU:IN MultiplicativeMonoid(U e_U);};TE CL AbstractMonoid:VI PU VirtualMonoid,PU AbstractMagma,PU PointedSet{PU:IN AbstractMonoid(M_U m_U,U e_U);}; TE IN MultiplicativeMonoid::MultiplicativeMonoid(U e_U):PointedSet(MO(e_U)){}TE IN AbstractMonoid::AbstractMonoid(M_U m_U,U e_U):AbstractMagma(MO(m_U)),PointedSet(MO(e_U)){} TE CL VirtualGroup:VI PU VirtualMonoid,VI PU VirtualPointedSet,VI PU VirtualNSet{};TE CL AdditiveGroup:VI PU VirtualGroup,PU AdditiveMonoid{PU:IN U Transfer(CO U& u);};TE CL AbstractGroup:VI PU VirtualGroup,PU AbstractMonoid,PU AbstractNSet{PU:IN AbstractGroup(M_U m_U,U e_U,I_U i_U);}; TE IN AbstractGroup::AbstractGroup(M_U m_U,U e_U,I_U i_U):AbstractMonoid(MO(m_U),MO(e_U)),AbstractNSet(MO(i_U)){}TE IN U AdditiveGroup::Transfer(CO U& u){RE -u;} TE CL VirtualRSet:VI PU UnderlyingSet{PU:VI U Action(CO R& r,U u)= 0;IN U PW(U u,CO R& r);IN U ScalarProduct(CO R& r,U u);};TE CL RegularRSet:VI PU VirtualRSet,PU MAGMA{PU:IN RegularRSet(MAGMA magma);IN U Action(CO U& r,U u);};TE RegularRSet(MAGMA magma)-> RegularRSet,MAGMA>;TE CL AbstractRSet:VI PU VirtualRSet{PU:O_U m_o_U;IN AbstractRSet(CO R& dummy0,CO U& dummy1,O_U o_U);IN AbstractRSet& OP=(CO AbstractRSet&)NE;IN U Action(CO R& r,U u);};TE CL AbstractModule:PU AbstractRSet,PU GROUP{PU:IN AbstractModule(CO R& dummy,O_U o_U,GROUP M);};TE AbstractModule(CO R& dummy,O_U o_U,GROUP M)-> AbstractModule,O_U,GROUP>;TE CL Module:VI PU VirtualRSet,PU AdditiveGroup{PU:IN U Action(CO R& r,U u);}; TE IN RegularRSet::RegularRSet(MAGMA magma):MAGMA(MO(magma)){}TE IN AbstractRSet::AbstractRSet(CO R& dummy0,CO U& dummy1,O_U o_U):m_o_U(MO(o_U)){ST_AS(is_invocable_r_v);}TE IN AbstractModule::AbstractModule(CO R& dummy,O_U o_U,GROUP M):AbstractRSet(dummy,M.One(),MO(o_U)),GROUP(MO(M)){ST_AS(is_same_v>);}TE IN AbstractRSet& AbstractRSet::OP=(CO AbstractRSet&)NE{RE *TH;}TE IN U RegularRSet::Action(CO U& r,U u){RE TH->Product(r,MO(u));}TE IN U AbstractRSet::Action(CO R& r,U u){RE m_o_U(r,MO(u));}TE IN U Module::Action(CO R& r,U u){RE MO(u *= r);}TE IN U VirtualRSet::PW(U u,CO R& r){RE Action(r,MO(u));}TE IN U VirtualRSet::ScalarProduct(CO R& r,U u){RE Action(r,MO(u));} /* ConstexprModulo (8KB) */ CEXPR(uint,P,998244353); #define RP Represent #define DeRP Derepresent TE CE INT Residue(INT n)NE{RE MO(n < 0?((((++n)*= -1)%= M)*= -1)+= M - 1:n < INT(M)?n:n %= M);}TE CE INT& ResidueP(INT& n)NE{CE CO uint trunc =(1 << 23)- 1;INT n_u = n >> 23;n &= trunc;INT n_uq =(n_u / 7)/ 17;n_u -= n_uq * 119;n += n_u << 23;RE n < n_uq?n += P - n_uq:n -= n_uq;} TE IN INT ModularInverse(CO INT& base,ll c){AS(base > 0);ll a[2]={0,1 % base};INT b[2]={base,INT((c %= base)< 0?c += base:c)};WH(b[1]!= 0){CO INT q = b[0]/ b[1];(a[0]-= q * a[1]% base)< 0?a[0]+= base:a[0];b[0]-= q * b[1];swap(a[0],a[1]);swap(b[0],b[1]);}AS(b[0]== 1 &&(a[0]* c - 1)% base == 0);RE a[0];} TE CL Mod;TE CL COantsForMod{PU:COantsForMod()= delete;ST CE CO uint g_memory_bound = 2e6;ST CE CO uint g_memory_le = M < g_memory_bound?M:g_memory_bound;ST CE uint g_M_minus = M - 1;ST CE int g_order = M - 1;ST CE int g_order_minus = g_order - 1;}; #define SFINAE_FOR_MOD enable_if_t>>* #define DC_OF_CM_FOR_MOD(OPR)CE bool OP OPR(CO Mod& n)CO NE #define DC_OF_AR_FOR_MOD(OPR,EX)CE Mod OP OPR(Mod n)CO EX; #define DF_OF_CM_FOR_MOD(OPR)TE CE bool Mod::OP OPR(CO Mod& n)CO NE{RE m_n OPR n.m_n;} #define DF_OF_AR_FOR_MOD(OPR,EX,LEFT,OPR2)TE CE Mod Mod::OP OPR(Mod n)CO EX{RE MO(LEFT OPR2 ## = *TH);}TE CE Mod OP OPR(T n0,CO Mod& n1)EX{RE MO(Mod(MO(n0))OPR ## = n1);} TE CL Mod{PU:uint m_n;CE Mod()NE;CE Mod(CO Mod& n)NE;CE Mod(Mod&& n)NE;TE CE Mod(T n)NE;CE Mod& OP=(Mod n)NE;CE Mod& OP+=(CO Mod& n)NE;CE Mod& OP-=(CO Mod& n)NE;CE Mod& OP*=(CO Mod& n)NE;IN Mod& OP/=(Mod n);CE Mod& OP^=(ll EX);CE Mod& OP<<=(ll n);CE Mod& OP>>=(ll n);CE Mod& OP++()NE;CE Mod OP++(int)NE;CE Mod& OP--()NE;CE Mod OP--(int)NE;DC_OF_CM_FOR_MOD(==);DC_OF_CM_FOR_MOD(!=);DC_OF_CM_FOR_MOD(<);DC_OF_CM_FOR_MOD(<=);DC_OF_CM_FOR_MOD(>);DC_OF_CM_FOR_MOD(>=);DC_OF_AR_FOR_MOD(+,NE);DC_OF_AR_FOR_MOD(-,NE);DC_OF_AR_FOR_MOD(*,NE);DC_OF_AR_FOR_MOD(/,);CE Mod OP^(ll EX)CO;CE Mod OP<<(ll n)CO;CE Mod OP>>(ll n)CO;CE Mod OP-()CO NE;CE VO swap(Mod& n)NE;CE CRUI RP()CO NE;ST CE Mod DeRP(uint n)NE;ST IN CO Mod& Factorial(CRL n);ST IN CO Mod& FactorialInverse(CRL n);ST IN Mod Combination(CRL n,CRL i);ST IN CO Mod& zero()NE;ST IN CO Mod& one()NE;ST CE uint GetModulo()NE;CE Mod& SignInvert()NE;IN Mod& Invert();CE Mod& PPW(ll EX)NE;CE Mod& NNPW(ll EX)NE;ST IN CO Mod& Inverse(CRI n);ST IN CO Mod& TwoPower(CRI n);ST IN CO Mod& TwoPowerInverse(CRI n);US COants = COantsForMod;}; US MP = Mod

; TE CE Mod::Mod()NE:m_n(){}TE CE Mod::Mod(CO Mod& n)NE:m_n(n.m_n){}TE CE Mod::Mod(Mod&& n)NE:m_n(MO(n.m_n)){}TE TE CE Mod::Mod(T n)NE:m_n(Residue(MO(n))){}TE CE Mod& Mod::OP=(Mod n)NE{m_n = MO(n.m_n);RE *TH;}TE CE Mod& Mod::OP+=(CO Mod& n)NE{(m_n += n.m_n)< M?m_n:m_n -= M;RE *TH;}TE CE Mod& Mod::OP-=(CO Mod& n)NE{m_n < n.m_n?(m_n += M)-= n.m_n:m_n -= n.m_n;RE *TH;}TE CE Mod& Mod::OP*=(CO Mod& n)NE{m_n = MO(ull(m_n)* n.m_n)% M;RE *TH;}TE <> CE MP& MP::OP*=(CO MP& n)NE{ull m_n_copy = m_n;m_n = MO((m_n_copy *= n.m_n)< P?m_n_copy:ResidueP(m_n_copy));RE *TH;}TE IN Mod& Mod::OP/=(Mod n){RE OP*=(n.Invert());}TE CE Mod& Mod::PPW(ll EX)NE{Mod pw{*TH};EX--;WH(EX != 0){(EX & 1)== 1?*TH *= pw:*TH;EX >>= 1;pw *= pw;}RE *TH;}TE CE Mod& Mod::NNPW(ll EX)NE{RE EX == 0?(m_n = 1,*TH):PPW(MO(EX));}TE CE Mod& Mod::OP^=(ll EX){if(EX < 0){m_n = ModularInverse(M,MO(m_n));EX *= -1;}RE NNPW(MO(EX));}TE CE Mod& Mod::OP<<=(ll n){RE *TH *=(n < 0 && -n < int(COants::g_memory_le))?TwoPowerInverse(- int(n)):(n >= 0 && n < int(COants::g_memory_le))?TwoPower(int(n)):Mod(2)^= MO(n);}TE CE Mod& Mod::OP>>=(ll n){RE *TH <<= MO(n *= -1);}TE CE Mod& Mod::OP++()NE{m_n < COants::g_M_minus?++m_n:m_n = 0;RE *TH;}TE CE Mod Mod::OP++(int)NE{Mod n{*TH};OP++();RE n;}TE CE Mod& Mod::OP--()NE{m_n == 0?m_n = COants::g_M_minus:--m_n;RE *TH;}TE CE Mod Mod::OP--(int)NE{Mod n{*TH};OP--();RE n;}DF_OF_CM_FOR_MOD(==);DF_OF_CM_FOR_MOD(!=);DF_OF_CM_FOR_MOD(>);DF_OF_CM_FOR_MOD(>=);DF_OF_CM_FOR_MOD(<);DF_OF_CM_FOR_MOD(<=);DF_OF_AR_FOR_MOD(+,NE,n,+);DF_OF_AR_FOR_MOD(-,NE,n.SignInvert(),+);DF_OF_AR_FOR_MOD(*,NE,n,*);DF_OF_AR_FOR_MOD(/,,n.Invert(),*);TE CE Mod Mod::OP^(ll EX)CO{RE MO(Mod(*TH)^= MO(EX));}TE CE Mod Mod::OP<<(ll n)CO{RE MO(Mod(*TH)<<= MO(n));}TE CE Mod Mod::OP>>(ll n)CO{RE MO(Mod(*TH)>>= MO(n));}TE CE Mod Mod::OP-()CO NE{RE MO(Mod(*TH).SignInvert());}TE CE Mod& Mod::SignInvert()NE{m_n > 0?m_n = M - m_n:m_n;RE *TH;}TE IN Mod& Mod::Invert(){m_n = m_n < COants::g_memory_le?Inverse(int(m_n)).m_n:ModularInverse(M,MO(m_n));RE *TH;}TE CE VO Mod::swap(Mod& n)NE{std::swap(m_n,n.m_n);}TE IN CO Mod& Mod::Inverse(CRI n){AS(0 < n && n < int(COants::g_memory_le));ST VE> memory ={zero(),one()};ST int le_curr = 2;WH(le_curr <= n){memory.push_back(DeRP(M - memory[M % le_curr].m_n * ull(M / le_curr)% M));le_curr++;}RE memory[n];}TE IN CO Mod& Mod::TwoPower(CRI n){AS(0 <= n && n < int(COants::g_memory_le));ST VE> memory ={one()};ST int le_curr = 1;WH(le_curr <= n){memory.push_back(memory.back()+ memory.back());le_curr++;}RE memory[n];}TE IN CO Mod& Mod::TwoPowerInverse(CRI n){AS(0 <= n && n < int(COants::g_memory_le));ST VE> memory ={one()};ST int le_curr = 1;WH(le_curr <= n){auto& m = memory.back().m_n;memory.push_back(DeRP(((m & 1)== 0?m:m + M)>> 1));le_curr++;}RE memory[n];}TE IN CO Mod& Mod::Factorial(CRL n){AS(n >= 0);if(ll(M)<= n){RE zero();}ST VE> memory ={one(),one()};ST int le_curr = 2;WH(le_curr <= n){memory.push_back(memory[le_curr - 1]* le_curr);le_curr++;}RE memory[n];}TE IN CO Mod& Mod::FactorialInverse(CRL n){AS(0 <= n && n < ll(M));ST VE> memory ={one(),one()};ST int le_curr = 2;WH(le_curr <= n){memory.push_back(memory[le_curr - 1]* Inverse(le_curr));le_curr++;}RE memory[n];}TE IN Mod Mod::Combination(CRL n,CRL i){RE 0 <= i && i <= n?Factorial(n)* FactorialInverse(i)* FactorialInverse(n - i):zero();}TE CE CRUI Mod::RP()CO NE{RE m_n;}TE CE Mod Mod::DeRP(uint n)NE{Mod n_copy{};n_copy.m_n = MO(n);RE n_copy;}TE IN CO Mod& Mod::zero()NE{ST CE CO Mod z{};RE z;}TE IN CO Mod& Mod::one()NE{ST CE CO Mod o{1};RE o;}TE CE uint Mod::GetModulo()NE{RE M;}TE IN Mod Inverse(CO Mod& n){RE MO(Mod(n).Invert());}TE CE Mod Power(Mod n,ll EX){RE MO(n ^= MO(EX));}TE CE VO swap(Mod& n0,Mod& n1)NE{n0.swap(n1);}TE IN string to_string(CO Mod& n)NE{RE to_string(n.RP())+ " + " + to_string(M)+ "Z";}TE IN IS& OP>>(IS& is,Mod& n){ll m;is >> m;n = m;RE is;}TE IN OS& OP<<(OS& os,CO Mod& n){RE os << n.RP();} /* Iteration (3KB) */ TE TY V,TY OPR> T LeftConnectiveProd(T t,CO V& f,OPR opr){for(auto& u:f){t = opr(MO(t),u);}RE MO(t);}TE TY V> IN T Sum(CO V& f){RE LeftConnectiveProd(T{0},f,[](T t0,CO U& u1){RE MO(t0 += u1);});} /* Sqrt (1KB) */ TE INT RoundUpSqrt(CO INT& n){ST_AS(is_same_v || is_same_v || is_same_v || is_same_v);AS(n >= 0);if(n <= 2){RE n;}CE INT r_max = is_same_v?46341:is_same_v?65536:is_same_v?3037000500:4294967296;CO INT n_minus = n - 1;INT l = 1,r = min(r_max,n);WH(l + 1 < r){CO INT m =(l + r)>> 1;(m <= n_minus / m?l:r)= m;}RE r;} #endif /* AAA 常設ライブラリは以上に挿入する。*/ #define INCLUDE_LIBRARY #include __FILE__ #endif /* INCLUDE_LIBRARY */ #endif /* INCLUDE_SUB */ #endif /* INCLUDE_MAIN */