#ifndef INCLUDE_MODE #define INCLUDE_MODE #define REACTIVE // #define USE_GETLINE #endif #ifdef INCLUDE_MAIN inline void Solve() { // 入力の受け取り。 CEXPR( int , bound_N , 15e5 ); CIN_ASSERT( N , 1 , bound_N ); CEXPR( int , bound_B , 1e2 ); CIN_ASSERT( B , 1 , bound_B ); CEXPR( int , bound_Q , 15e2 ); CIN_ASSERT( Q , 1 , bound_Q ); // 二分木をHL分解(二分木の定義から、indexの小さいnodeがheaviest)。 vector dfs{ 1 } , HL_inv( N+1 ); int length = 0; while( !dfs.empty() ){ int temp = dfs.back(); dfs.pop_back(); if( temp <= N ){ HL_inv[temp] = length++; dfs.push_back( temp << 1 | 1 ); dfs.push_back( temp << 1 ); } } // 二分木の各ノードの部分木に対応する区間の右端の計算。 vector R( N + 1 ); FOREQINV( i , N , 1 ){ int temp = i << 1; R[i] = temp <= N ? temp < N ? R[temp | 1] : R[temp] : HL_inv[i]; } // mod Bの整数型。Derepresent()で構築し、Represent()で代表の整数値を取り出す。 using mint = DynamicMod; mint::SetModulo( B ); // HL分解後の配列をmod Bで計算。 vector A( N ); FOREQ( i , 1 , N ){ ++( A[HL_inv[i]] = A[HL_inv[i-1]] ); } // 写像のモノイド。 using Func = vector; auto composition = [&]( const Func& f0 , const Func& f1 ){ if( f0.empty() ){ return f1; } else if( f1.empty() ){ return f0; } auto answer = f0; FOR( j , 0 , B ){ answer[j] = f0[f1[j].Represent()]; } return answer; }; AbstractMonoid F{ composition , Func() }; // 写像の値への作用。 auto application = [&]( const Func& f , const mint& n ){ return f[n.Represent()]; }; AbstractRSet X{ Func() , mint() , application }; // 写像の頻度表への作用。 using Hind = vector; auto action = [&]( const Func& f , const Hind& h ){ if( f.empty() ){ return h; } vector answer( B , 0 ); FOR( j , 0 , B ){ answer[f[j].Represent()] += h[j]; } return answer; }; // 頻度表の和倍。 auto add = [&]( Hind h0 , const Hind& h1 ){ FOR( j , 0 , B ){ h0[j] += h1[j]; } return move( h0 ); }; AbstractMonoid H{ add , Hind( B ) }; // 頻度表のスカラー倍。 auto scalar_product = [&]( Hind h , const int& n ){ return n * move( h ); }; AbstractBiModule M{ Func() , 0 , action , scalar_product , H }; // 1つの値を頻度表に加算。 auto trans = [&]( Hind h , const mint& n , const int& c ){ h[n.Represent()] += c; return move( h ); }; // 写像の値への作用を遅延評価して頻度表を計算する平方分割。 int bucket = SqrtDecompositionCoordinate::Sqrt( B * N ); EquivariantLazySqrtDecomposition lsd{ F , X , M , trans , move( A ) , bucket }; CEXPR( ll , bound_d , 1e18 ); REPEAT( Q ){ // クエリの受け取り。 CIN_ASSERT( i , 1 , N ); CIN_ASSERT( d , 0 , bound_d ); // 作用する写像を構成。 Func f( B ); FOR( j , 0 , B ){ ++( f[j] = Power( mint::Derepresent( j ) , d ) ); } // 作用の遅延評価。 lsd.IntervalAct( HL_inv[i] , R[i] , f ); // 頻度表の区間和の計算。 Hind h = lsd.IntervalProduct( HL_inv[i] , R[i] ); // 区間和の計算。 mint answer{}; FOR( j , 0 , B ){ answer += h[j] * j; } // 区間和の出力。 COUT( answer ); } } REPEAT_MAIN(1); #else // INCLUDE_MAIN #ifdef INCLUDE_LIBRARY // https://github.com/p-adic/cpp // VVV ライブラリは以下に挿入する。 // 圧縮用 #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 reSZ resize #define DF_OF_AR_FOR_VE(V,OPR)TE IN V& OP OPR ## =(V& a,CO T& t){for(auto& s:a){s OPR ## = t;}RE a;}TE IN V& OP OPR ## =(V& a0,CO V& a1){AS(a0.SZ()<= a1.SZ());auto IT0 = a0.BE(),EN0 = a0.EN();auto IT1 = a1.BE();WH(IT0 != EN0){*(IT0++)OPR ## = *(IT1++);}RE a0;}TE IN V OP OPR(V a,CO U& u){RE MO(a OPR ## = u);} #define DF_OF_INCREMENT_FOR_VE(V,INCR)TE IN V& OP INCR(V& a){for(auto& i:a){INCR i;}RE a;} #define DF_OF_ARS_FOR_VE(V)DF_OF_AR_FOR_VE(V,+);DF_OF_AR_FOR_VE(V,-);DF_OF_AR_FOR_VE(V,*);DF_OF_AR_FOR_VE(V,/);DF_OF_AR_FOR_VE(V,%);DF_OF_INCREMENT_FOR_VE(V,++);DF_OF_INCREMENT_FOR_VE(V,--);TE IN V OP*(CO T& scalar,V v){for(auto& t:v){v *= t;}RE MO(v);} DF_OF_ARS_FOR_VE(VE); #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));} 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);} #define RP Represent #define DeRP Derepresent TE CE INT1 RS(INT1 n,CO INT2& M)NE{RE MO(n < 0?((((++n)*= -1)%= M)*= -1)+= M - 1:n < M?n:n %= M);} TE CL DynamicMods;TE CL COantsForDynamicMods{PU:COantsForDynamicMods()= delete;ST uint g_M;ST uint g_M_minus;ST int g_order_minus_1;ST int g_order_minus_1_neg;ST bool g_M_is_prime;}; TE uint COantsForDynamicMods::g_M = 0;TE uint COantsForDynamicMods::g_M_minus = -1;TE int COantsForDynamicMods::g_order_minus_1 = 0;TE int COantsForDynamicMods::g_order_minus_1_neg = 0;TE bool COantsForDynamicMods::g_M_is_prime = false; #define DC_OF_CM_FOR_DYNAMIC_MOD(OPR)IN bool OP OPR(CO DynamicMods& n)CO NE #define DC_OF_AR_FOR_DYNAMIC_MOD(OPR,EX)IN DynamicMods OP OPR(DynamicMods n)CO EX; #define DF_OF_CM_FOR_DYNAMIC_MOD(OPR)TE IN bool DynamicMods::OP OPR(CO DynamicMods& n)CO NE{RE m_n OPR n.m_n;} #define DF_OF_AR_FOR_DYNAMIC_MOD(OPR,EX,LEFT,OPR2)TE IN DynamicMods DynamicMods::OP OPR(DynamicMods n)CO EX{RE MO(LEFT OPR2 ## = *TH);}TE IN DynamicMods OP OPR(T n0,CO DynamicMods& n1)EX{RE MO(DynamicMods(MO(n0))OPR ## = n1);} TE CL DynamicMods{PU:uint m_n;IN DynamicMods()NE;IN DynamicMods(CO DynamicMods& n)NE;IN DynamicMods(DynamicMods&& n)NE;TE IN DynamicMods(T n)NE;IN DynamicMods& OP=(DynamicMods n)NE;IN DynamicMods& OP+=(CO DynamicMods& n)NE;IN DynamicMods& OP-=(CO DynamicMods& n)NE;IN DynamicMods& OP*=(CO DynamicMods& n)NE;IN DynamicMods& OP/=(DynamicMods n);TE IN DynamicMods& OP<<=(INT n);TE IN DynamicMods& OP>>=(INT n);IN DynamicMods& OP++()NE;IN DynamicMods OP++(int)NE;IN DynamicMods& OP--()NE;IN DynamicMods OP--(int)NE;DC_OF_CM_FOR_DYNAMIC_MOD(==);DC_OF_CM_FOR_DYNAMIC_MOD(!=);DC_OF_CM_FOR_DYNAMIC_MOD(<);DC_OF_CM_FOR_DYNAMIC_MOD(<=);DC_OF_CM_FOR_DYNAMIC_MOD(>);DC_OF_CM_FOR_DYNAMIC_MOD(>=);DC_OF_AR_FOR_DYNAMIC_MOD(+,NE);DC_OF_AR_FOR_DYNAMIC_MOD(-,NE);DC_OF_AR_FOR_DYNAMIC_MOD(*,NE);DC_OF_AR_FOR_DYNAMIC_MOD(/,);TE IN DynamicMods OP^(INT EX)CO;TE IN DynamicMods OP<<(INT n)CO;TE IN DynamicMods OP>>(INT n)CO;IN DynamicMods OP-()CO NE;IN DynamicMods& SignInvert()NE;IN DynamicMods& Invert();TE IN DynamicMods& PW(INT EX);IN VO swap(DynamicMods& n)NE;IN CRUI RP()CO NE;ST IN DynamicMods DeRP(uint n)NE;ST IN CO DynamicMods& Inverse(CRUI n);ST IN CO DynamicMods& Factorial(CRUI n);ST IN CO DynamicMods& FactorialInverse(CRUI n);ST IN DynamicMods Combination(CRUI n,CRUI i);ST IN CO DynamicMods& zero()NE;ST IN CO DynamicMods& one()NE;ST IN CRUI GetModulo()NE;ST IN VO SetModulo(CRUI M,CRI order_minus_1 = -1)NE;TE IN DynamicMods& PositivePW(INT EX)NE;TE IN DynamicMods& NonNegativePW(INT EX)NE;US COants = COantsForDynamicMods;}; US DynamicMod = DynamicMods<0>; TE IN DynamicMods::DynamicMods()NE:m_n(){}TE IN DynamicMods::DynamicMods(CO DynamicMods& n)NE:m_n(n.m_n){}TE IN DynamicMods::DynamicMods(DynamicMods&& n)NE:m_n(MO(n.m_n)){}TE TE IN DynamicMods::DynamicMods(T n)NE:m_n(RS(uint(MO(n)),COants::g_M)){ST_AS(is_COructible_v >);}TE IN DynamicMods& DynamicMods::OP=(DynamicMods n)NE{m_n = MO(n.m_n);RE *TH;}TE IN DynamicMods& DynamicMods::OP+=(CO DynamicMods& n)NE{(m_n += n.m_n)< COants::g_M?m_n:m_n -= COants::g_M;RE *TH;}TE IN DynamicMods& DynamicMods::OP-=(CO DynamicMods& n)NE{m_n < n.m_n?(m_n += COants::g_M)-= n.m_n:m_n -= n.m_n;RE *TH;}TE IN DynamicMods& DynamicMods::OP*=(CO DynamicMods& n)NE{m_n = RS(MO(ull(m_n)* n.m_n),COants::g_M);RE *TH;}TE IN DynamicMods& DynamicMods::OP/=(DynamicMods n){RE OP*=(n.Invert());}TE TE IN DynamicMods& DynamicMods::OP<<=(INT n){AS(n >= 0);RE *TH *= DynamicMods(2).NonNegativePW(MO(n));}TE TE IN DynamicMods& DynamicMods::OP>>=(INT n){AS(n >= 0);WH(n-- > 0){((m_n & 1)== 0?m_n:m_n += COants::g_M)>>= 1;}RE *TH;}TE IN DynamicMods& DynamicMods::OP++()NE{m_n < COants::g_M_minus?++m_n:m_n = 0;RE *TH;}TE IN DynamicMods DynamicMods::OP++(int)NE{DynamicMods n{*TH};OP++();RE n;}TE IN DynamicMods& DynamicMods::OP--()NE{m_n == 0?m_n = COants::g_M_minus:--m_n;RE *TH;}TE IN DynamicMods DynamicMods::OP--(int)NE{DynamicMods n{*TH};OP--();RE n;}DF_OF_CM_FOR_DYNAMIC_MOD(==);DF_OF_CM_FOR_DYNAMIC_MOD(!=);DF_OF_CM_FOR_DYNAMIC_MOD(>);DF_OF_CM_FOR_DYNAMIC_MOD(>=);DF_OF_CM_FOR_DYNAMIC_MOD(<);DF_OF_CM_FOR_DYNAMIC_MOD(<=);DF_OF_AR_FOR_DYNAMIC_MOD(+,NE,n,+);DF_OF_AR_FOR_DYNAMIC_MOD(-,NE,n.SignInvert(),+);DF_OF_AR_FOR_DYNAMIC_MOD(*,NE,n,*);DF_OF_AR_FOR_DYNAMIC_MOD(/,,n.Invert(),*);TE TE IN DynamicMods DynamicMods::OP^(INT EX)CO{RE MO(DynamicMods(*TH).PW(MO(EX)));}TE TE IN DynamicMods DynamicMods::OP<<(INT n)CO{RE MO(DynamicMods(*TH)<<= MO(n));}TE TE IN DynamicMods DynamicMods::OP>>(INT n)CO{RE MO(DynamicMods(*TH)>>= MO(n));}TE IN DynamicMods DynamicMods::OP-()CO NE{RE MO(DynamicMods(*TH).SignInvert());}TE IN DynamicMods& DynamicMods::SignInvert()NE{m_n > 0?m_n = COants::g_M - m_n:m_n;RE *TH;}TE IN DynamicMods& DynamicMods::Invert(){RE m_n <(COants::g_M_is_prime?1e6:3e4)?*TH = Inverse(m_n):NonNegativePW(COants::g_order_minus_1);}TE TE IN DynamicMods& DynamicMods::PositivePW(INT EX)NE{DynamicMods PW{*TH};EX--;WH(EX != 0){(EX & 1)== 1?*TH *= PW:*TH;EX >>= 1;PW *= PW;}RE *TH;}TE TE IN DynamicMods& DynamicMods::NonNegativePW(INT EX)NE{RE EX == 0?(m_n = 1,*TH):PositivePW(MO(EX));}TE TE IN DynamicMods& DynamicMods::PW(INT EX){bool neg = EX < 0;RE neg?PositivePW(MO(EX *= COants::g_order_minus_1_neg)):NonNegativePW(MO(EX));}TE IN VO DynamicMods::swap(DynamicMods& n)NE{std::swap(m_n,n.m_n);}TE IN CO DynamicMods& DynamicMods::Inverse(CRUI n){ST VE> memory ={zero(),one()};ST uint LE_curr = 2;AS(COants::g_M == 1||(0 < n && n < COants::g_M));WH(LE_curr <= n){memory.push_back(COants::g_M_is_prime?DeRP(COants::g_M - memory[COants::g_M % LE_curr].m_n * ull(COants::g_M / LE_curr)% COants::g_M):DeRP(n).NonNegativePW(COants::g_order_minus_1));LE_curr++;}RE memory[n];}TE IN CO DynamicMods& DynamicMods::Factorial(CRUI n){ST VE> memory ={one(),one()};ST uint LE_curr = 2;if(COants::g_M <= n){RE zero();}WH(LE_curr <= n && memory.back().m_n != 0){memory.push_back(memory.back()* DeRP(LE_curr));LE_curr++;}RE LE_curr <= n?memory.back():memory[n];}TE IN CO DynamicMods& DynamicMods::FactorialInverse(CRUI n){ST VE> memory ={one(),one()};ST uint LE_curr = 2;WH(LE_curr <= n){memory.push_back(memory[LE_curr - 1]* Inverse(LE_curr));LE_curr++;}RE memory[n];}TE IN DynamicMods DynamicMods::Combination(CRUI n,CRUI i){RE i <= n?Factorial(n)* FactorialInverse(i)* FactorialInverse(n - i):zero();}TE IN CRUI DynamicMods::RP()CO NE{RE m_n;}TE IN DynamicMods DynamicMods::DeRP(uint n)NE{DynamicMods n_copy{};n_copy.m_n = MO(n);RE n_copy;}TE IN CO DynamicMods& DynamicMods::zero()NE{ST CO DynamicMods z{};RE z;}TE IN CO DynamicMods& DynamicMods::one()NE{ST CO DynamicMods o{1};RE o;}TE IN CRUI DynamicMods::GetModulo()NE{RE COants::g_M;}TE IN VO DynamicMods::SetModulo(CRUI M,CRI order_minus_1)NE{COants::g_M = M;COants::g_M_minus = M - 1;COants::g_order_minus_1 = order_minus_1 == -1?M - 2:order_minus_1;COants::g_order_minus_1_neg = -COants::g_order_minus_1;COants::g_M_is_prime = order_minus_1 == -1;}TE IN DynamicMods Inverse(CO DynamicMods& n){RE MO(DynamicMods(n).Invert());}TE IN DynamicMods PW(DynamicMods n,INT EX){RE MO(n.PW(MO(EX)));}TE IN VO swap(DynamicMods& n0,DynamicMods& n1)NE{n0.swap(n1);}TE IN string to_string(CO DynamicMods& n)NE{RE to_string(n.RP())+ " + " + to_string(DynamicMods::GetModulo())+ "Z";}TE IN IS& OP>>(IS& is,DynamicMods& n){ll m;is >> m;n = m;RE is;}TE IN OS& OP<<(OS& os,CO DynamicMods& n){RE os << n.RP();} class SqrtDecompositionCoordinate { protected: int m_N; int m_N_sqrt; // m_N / m_N_sqrt 以上である最小の整数。 int m_N_d; // m_N 以上である最小の m_N_sqrt の倍数。 int m_N_m; public: inline SqrtDecompositionCoordinate( const int& N = 0 ); inline SqrtDecompositionCoordinate( const int& N , const int& N_sqrt ); // 2乗がN以上である最小の正整数を返す。 static inline int Sqrt( const int& N ) noexcept; }; inline SqrtDecompositionCoordinate::SqrtDecompositionCoordinate( const int& N ) : SqrtDecompositionCoordinate( N , Sqrt( N ) ) {}; inline SqrtDecompositionCoordinate::SqrtDecompositionCoordinate( const int& N , const int& 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 ) {} inline int SqrtDecompositionCoordinate::Sqrt( const int& N ) noexcept { if( N <= 1 ){ return 1; } int l = 0 , r = N; while( l + 1 < r ){ int m = ( l + r ) >> 1; ( m <= ( N - 1 ) / m ? l : r ) = m; } return r; } // TRANSは写像trans:U \times S \times N ->Uに相当する型である。 // 入力の範囲内で要件 // (1) LはRの基点付きマグマ構造である。 // (2) M0はSの左L集合構造であって、Lの基点がSの恒等変換に対応する。 // (3) M1はUの左L作用付き非可換N加群構造であって、Lの基点がMの恒等変換に対応する。 // (4) R=intならばUのL作用と非可換N加群構造が整合的である。 // (5) あるL同変写像univ:S->Uが存在して、任意の(u,s,n) in U \times S \times N // に対してtrans(u,s,n) = u*univ(s)*nである。 // を満たす場合にのみサポート。 // 区間作用を行わない場合もm_L.Point()の作用を区間積に用いるため、 // dummyにせずRegularRSet(MultiplicativeMonoid(1))などを用いる必要があることに注意。 // 配列による初期化O(N) // 一点代入O(N^{1/2})はなし。 // 区間代入O(N^{1/2})(M1の非可換N加群性を使う) // M0.Act()による一点作用はなし。 // M0.Act()による区間作用O(N^{1/2})(univのL同変性を使う) // 一点取得O(1) // transに関する区間積取得O(N^{1/2})(M1のモノイド性を使う) template class EquivariantLazySqrtDecomposition : public SqrtDecompositionCoordinate { protected: PT_MAGMA m_L; R_SET m_M0; RN_BIMODULE m_M1; TRANS m_trans; vector m_a; vector m_b; // 代入の遅延評価。過去の作用の遅延評価を棄却する。 // 区間作用はここに即座に適用する。 vector m_lazy_substitution; vector m_suspended; // 作用の遅延評価。 vector m_lazy_action; public: // vectorを構築する時は // vector t( N , EquivariantLazySqrtDecomposition{L,M0,M1,vector()} ); // としてInitialiseすればよい。 template inline EquivariantLazySqrtDecomposition( PT_MAGMA L , R_SET M0 , RN_BIMODULE M1 , TRANS trans , vector a , const Args&... args ); template inline void Initialise( Args&&... args ); inline void Set( const int& i , const S& s ); inline void IntervalSet( const int& i_start , const int& i_final , const S& s ); inline void IntervalAct( const int& i_start , const int& i_final , const R& r ); inline S operator[]( const int& i ); inline S Get( const int& i ); inline U IntervalProduct( const int& i_start , const int& i_final ); private: inline U Univ( const S& s , const int& n ); inline void SetProduct( const int& i ); inline void SolveSuspendedSubstitution( const int& d , const S& s ); inline void IntervalSet_Body( const int& i_min , const int& i_ulim , const S& s ); // 細かく区間を指定した方が速いが、そのi_minとi_ulimの位置関係でバグらせやすいのでこのまま。 inline void SolveSuspendedAction( const int& d ); inline void IntervalAct_Body( const int& i_min , const int& i_ulim , const R& r ); inline U IntervalProduct_Body( const int& i_min , const int& i_ulim ); }; template EquivariantLazySqrtDecomposition( PT_MAGMA L , R_SET M0 , RN_BIMODULE M1 , TRANS trans , vector a , const Args&... args ) -> EquivariantLazySqrtDecomposition,PT_MAGMA,S,R_SET,inner_t,RN_BIMODULE,TRANS>; template template inline EquivariantLazySqrtDecomposition::EquivariantLazySqrtDecomposition( PT_MAGMA L , R_SET M0 , RN_BIMODULE M1 , TRANS trans , vector a , const Args&... args ) : SqrtDecompositionCoordinate( a.size() , args... ) , m_L( move( L ) ) , m_M0( move( M0 ) ) , m_M1( move( M1 ) ) , m_trans( move( trans ) ) , m_a( move( a ) ) , m_b( m_N_d , m_M1.One() ) , m_lazy_substitution( m_N_d ) , m_suspended( m_N_d ) , m_lazy_action( m_N_d , m_L.Point() ) { static_assert( is_same_v> && is_same_v> && is_same_v> && is_invocable_r_v ); if( m_N_m > 0 ){ m_a.resize( m_N_m , m_a[0] ); } 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_trans( move( m_bd ) , m_a[i] , 1 ); } i_min = i_ulim; i_ulim += m_N_sqrt; } } template template inline void EquivariantLazySqrtDecomposition::Initialise( Args&&...args ) { EquivariantLazySqrtDecomposition temp{ m_L , m_M0 , m_M1 , forward( args )... }; SqrtDecompositionCoordinate::operator=( temp ); m_a = move( temp.m_a ); m_b = move( temp.m_b ); m_lazy_substitution = move( temp.m_lazy_substitution ); m_suspended = move( temp.m_suspended ); m_lazy_action = move( temp.m_lazy_action ); } template inline void EquivariantLazySqrtDecomposition::IntervalSet( const int& i_start , const int& i_final , const S& s ) { const int i_min = max( i_start , 0 ); const int i_ulim = min( i_final + 1 , m_N ); const int d_0 = ( i_min + m_N_sqrt - 1 ) / m_N_sqrt; const int d_1 = max( d_0 , i_ulim / m_N_sqrt ); const int d_0_N_sqrt = d_0 * m_N_sqrt; const int d_1_N_sqrt = d_1 * m_N_sqrt; const int i_0 = min( d_0_N_sqrt , i_ulim ); const int i_1 = max( i_0 , d_1_N_sqrt ); if( i_min < i_0 ){ // この時d_0 > 0になる。 const int d_0_minus = d_0 - 1; const int d_0_N_sqrt_minus = d_0_N_sqrt - m_N_sqrt; U& m_bd = m_b[d_0_minus]; vector::reference m_suspended_d = m_suspended[d_0_minus]; if( m_suspended_d ){ const S& 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 , s ); IntervalSet_Body( i_0 , d_0_N_sqrt , m_lazy_substitution_d ); m_suspended_d = false; // 非可換N加群性を使った。 m_bd = m_trans( m_trans( Univ( m_lazy_substitution_d , i_min - d_0_N_sqrt_minus ) , s , i_0 - i_min ) , m_lazy_substitution_d , d_0_N_sqrt - i_0 ); } else { SolveSuspendedAction( d_0_minus ); IntervalSet_Body( i_min , i_0 , s ); m_bd = m_M1.Product( m_trans( IntervalProduct_Body( d_0_N_sqrt_minus , i_min ) , s , i_0 - i_min ) , IntervalProduct_Body( i_0 , d_0_N_sqrt ) ); } } const U power = Univ( s , m_N_sqrt ); for( int d = d_0 ; d < d_1 ; d++ ){ m_b[d] = power; m_lazy_substitution[d] = s; m_suspended[d] = true; m_lazy_action[d] = m_L.Point(); } if( i_1 < i_ulim ){ // この時d_1 < m_N_dになる。 const int d_1_N_sqrt_plus = d_1_N_sqrt + m_N_sqrt; U& m_bd = m_b[d_1]; vector::reference m_suspended_d = m_suspended[d_1]; if( m_suspended_d ){ const S& 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 , s ); IntervalSet_Body( i_ulim , d_1_N_sqrt_plus , m_lazy_substitution_d ); m_suspended_d = false; m_bd = m_trans( m_trans( Univ( m_lazy_substitution_d , i_1 - d_1_N_sqrt ) , s , i_ulim - i_1 ) , m_lazy_substitution_d , d_1_N_sqrt_plus - i_ulim ); } else { SolveSuspendedAction( d_1 ); IntervalSet_Body( i_1 , i_ulim , s ); m_bd = m_M1.Product( m_trans( IntervalProduct_Body( d_1_N_sqrt , i_1 ) , s , i_ulim - i_1 ) , IntervalProduct_Body( i_ulim , d_1_N_sqrt_plus ) ); } } return; } template inline void EquivariantLazySqrtDecomposition::IntervalAct( const int& i_start , const int& i_final , const R& r ) { if( r != m_L.Point() ){ const int i_min = max( i_start , 0 ); const int i_ulim = min( i_final + 1 , m_N ); const int d_0 = ( i_min + m_N_sqrt - 1 ) / m_N_sqrt; const int d_1 = max( d_0 , i_ulim / m_N_sqrt ); const int d_0_N_sqrt = d_0 * m_N_sqrt; const int d_1_N_sqrt = d_1 * m_N_sqrt; const int i_0 = min( d_0_N_sqrt , i_ulim ); const int i_1 = max( i_0 , d_1_N_sqrt ); if( i_min < i_0 ){ // この時d_0 > 0になる。 const int d_0_minus = d_0 - 1; const int d_0_N_sqrt_minus = d_0_N_sqrt - m_N_sqrt; vector::reference m_suspended_d = m_suspended[d_0_minus]; if( m_suspended_d ){ S& m_lazy_substitution_d = m_lazy_substitution[d_0_minus]; U& m_bd = m_b[d_0_minus]; const S s = m_M0.Action( r , m_lazy_substitution_d ); IntervalSet_Body( d_0_N_sqrt_minus , i_min , m_lazy_substitution_d ); IntervalSet_Body( i_min , i_0 , s ); IntervalSet_Body( i_0 , d_0_N_sqrt , m_lazy_substitution_d ); m_suspended_d = false; // 非可換N加群性を使った。 m_bd = m_trans( m_trans( Univ( m_lazy_substitution_d , i_min - d_0_N_sqrt_minus ) , s , i_0 - i_min ) , m_lazy_substitution_d , d_0_N_sqrt - i_0 ); } else { R& m_lazy_action_d = m_lazy_action[d_0_minus]; if( m_lazy_action_d == m_L.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 = m_L.Point(); } SetProduct( d_0_minus ); } } for( int d = d_0 ; d < d_1 ; d++ ){ U& m_bd = m_b[d]; m_bd = m_M1.ScalarProduct( r , m_bd ); if( m_suspended[d] ){ S& m_lazy_substitution_d = m_lazy_substitution[d]; m_lazy_substitution_d = m_M0.Action( 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 ); } } if( i_1 < i_ulim ){ // この時d_1 < m_N_dになる。 const int d_1_N_sqrt_plus = d_1_N_sqrt + m_N_sqrt; vector::reference m_suspended_d = m_suspended[d_1]; if( m_suspended_d ){ S& m_lazy_substitution_d = m_lazy_substitution[d_1]; U& m_bd = m_b[d_1]; const S s = m_M0.Action( r , m_lazy_substitution_d ); IntervalSet_Body( d_1_N_sqrt , i_1 , m_lazy_substitution_d ); IntervalSet_Body( i_1 , i_ulim , s ); IntervalSet_Body( i_ulim , d_1_N_sqrt_plus , m_lazy_substitution_d ); m_suspended_d = false; // 非可換N加群性を使った。 m_bd = m_trans( m_trans( Univ( m_lazy_substitution_d , i_1 - d_1_N_sqrt ) , s , i_ulim - i_1 ) , m_lazy_substitution_d , d_1_N_sqrt_plus - i_ulim ); } else { R& m_lazy_action_d = m_lazy_action[d_1]; if( m_lazy_action_d == m_L.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 = m_L.Point(); } SetProduct( d_1 ); } } } return; } template inline U EquivariantLazySqrtDecomposition::IntervalProduct_Body( const int& i_min , const int& i_ulim ) { U answer = m_M1.One(); for( int i = i_min ; i < i_ulim ; i++ ){ answer = m_trans( move( answer ) , m_a[i] , 1 ); } return answer; } template inline U EquivariantLazySqrtDecomposition::Univ( const S& s , const int& n ) { return m_trans( m_M1.One() , s , n ); } template inline void EquivariantLazySqrtDecomposition::SetProduct( const int& d ) { U& m_bd = m_b[d] = m_M1.One(); const int i_min = d * m_N_sqrt; const int i_ulim = i_min + m_N_sqrt; for( int i = i_min ; i < i_ulim ; i++ ){ m_bd = m_trans( move( m_bd ) , m_a[i] , 1 ); } return; } template inline void EquivariantLazySqrtDecomposition::SolveSuspendedSubstitution( const int& d , const S& s ) { const int i_min = d * m_N_sqrt; IntervalSet_Body( i_min , i_min + m_N_sqrt , s ); m_suspended[d] = false; return; } template inline void EquivariantLazySqrtDecomposition::IntervalSet_Body( const int& i_min , const int& i_ulim , const S& s ) { for( int i = i_min ; i < i_ulim ; i++ ){ m_a[i] = s; } return; } template inline void EquivariantLazySqrtDecomposition::SolveSuspendedAction( const int& d ) { R& m_lazy_action_d = m_lazy_action[d]; if( m_lazy_action_d != m_L.Point() ){ const int i_min = d * m_N_sqrt; const int i_ulim = i_min + m_N_sqrt; IntervalAct_Body( i_min , i_ulim , m_lazy_action_d ); U& m_bd = m_b[d]; m_bd = m_M1.ScalarProduct( m_lazy_action_d , m_bd ); m_lazy_action_d = m_L.Point(); } return; } template inline S EquivariantLazySqrtDecomposition::operator[]( const int& i ) { assert( 0 <= i && i < m_N ); const int d = i / m_N_sqrt; return m_suspended[d] ? m_lazy_substitution[d] : m_M0.Action( m_lazy_action[d] , m_a[i] ); } template inline S EquivariantLazySqrtDecomposition::Get( const int& i ) { return operator[]( i ); } template inline U EquivariantLazySqrtDecomposition::IntervalProduct( const int& i_start , const int& i_final ) { const int i_min = max( i_start , 0 ); const int i_ulim = min( i_final + 1 , m_N ); const int d_0 = ( i_min + m_N_sqrt - 1 ) / m_N_sqrt; const int d_1 = max( d_0 , i_ulim / m_N_sqrt ); const int i_0 = min( d_0 * m_N_sqrt , i_ulim ) ; const int i_1 = max( i_0 , d_1 * m_N_sqrt ); U answer = m_M1.One(); if( i_min < i_0 ){ // この時d_0 > 0になる。 const int d_0_minus = d_0 - 1; // 非可換N加群性を使った。 answer = m_suspended[d_0_minus] ? m_trans( move( answer ) , m_lazy_substitution[d_0_minus] , i_0 - i_min ) : m_M1.ScalarProduct( m_lazy_action[d_0_minus] , IntervalProduct_Body( i_min , i_0 ) ); } for( int d = d_0 ; d < d_1 ; d++ ){ answer = m_M1.Product( move( answer ) , m_b[d] ); } if( i_1 < i_ulim ){ // この時d_1 < m_N_dになる。 // 非可換N加群性を使った。 answer = m_suspended[d_1] ? m_trans( move( answer ), m_lazy_substitution[d_1] , i_ulim - i_1 ) : m_M1.Product( move( answer ), m_M1.ScalarProduct( m_lazy_action[d_1] , IntervalProduct_Body( i_1 , i_ulim ) ) ); } return answer; } template inline void EquivariantLazySqrtDecomposition::IntervalAct_Body( const int& i_min , const int& i_ulim , const R& r ) { for( int i = i_min ; i < i_ulim ; i++ ){ S& m_ai = m_a[i]; m_ai = m_M0.Action( r , m_ai ); } return; } // AAA ライブラリは以上に挿入する。 #define INCLUDE_MAIN #include __FILE__ #else // INCLUDE_LIBRARY #ifdef DEBUG #define _GLIBCXX_DEBUG #define DEXPR( LL , BOUND , VALUE1 , VALUE2 ) CEXPR( LL , BOUND , VALUE2 ) #define SIGNAL signal( SIGABRT , &AlertAbort ); #define ASSERT( A , MIN , MAX ) CERR( "ASSERTチェック: " , ( MIN ) , ( ( MIN ) <= A ? "<=" : ">" ) , A , ( A <= ( MAX ) ? "<=" : ">" ) , ( MAX ) ); assert( ( MIN ) <= A && A <= ( MAX ) ) #define CERR( ... ) VariadicCout( cerr , __VA_ARGS__ ) << endl #define COUT( ... ) VariadicCout( cout << "出力: " , __VA_ARGS__ ) << endl #define CERR_A( A , N ) OUTPUT_ARRAY( cerr , A , N ) << endl #define COUT_A( A , N ) cout << "出力: "; OUTPUT_ARRAY( cout , A , N ) << endl #define CERR_ITR( A ) OUTPUT_ITR( cerr , A ) << endl #define COUT_ITR( A ) cout << "出力: "; OUTPUT_ITR( cout , A ) << endl #else #pragma GCC optimize ( "O3" ) #pragma GCC optimize ( "unroll-loops" ) #pragma GCC target ( "sse4.2,fma,avx2,popcnt,lzcnt,bmi2" ) #define SIGNAL #define DEXPR( LL , BOUND , VALUE1 , VALUE2 ) CEXPR( LL , BOUND , VALUE1 ) #define ASSERT( A , MIN , MAX ) assert( ( MIN ) <= A && A <= ( MAX ) ) #define CERR( ... ) #define COUT( ... ) VariadicCout( cout , __VA_ARGS__ ) << ENDL #define CERR_A( N , A ) #define COUT_A( N , A ) OUTPUT_ARRAY( cout , N , A ) << ENDL #define CERR_ITR( A ) #define COUT_ITR( A ) OUTPUT_ITR( cout , A ) << ENDL #endif #ifdef REACTIVE #define ENDL endl #else #define ENDL "\n" #endif #ifdef USE_GETLINE #define SET_LL( A ) { GETLINE( A ## _str ); A = stoll( A ## _str ); } #define GETLINE_SEPARATE( SEPARATOR , ... ) string __VA_ARGS__; VariadicGetline( cin , SEPARATOR , __VA_ARGS__ ) #define GETLINE( ... ) GETLINE_SEPARATE( '\n' , __VA_ARGS__ ) #else #define SET_LL( A ) cin >> A #define CIN( LL , ... ) LL __VA_ARGS__; VariadicCin( cin , __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 ); FOR( VARIABLE_FOR_CIN_AA , 0 , N0 ){ SET_A( I1 , N1 , VAR[VARIABLE_FOR_CIN_AA + I0] ); } #endif #include using namespace std; #define REPEAT_MAIN( BOUND ) int main(){ ios_base::sync_with_stdio( false ); cin.tie( nullptr ); SIGNAL; CEXPR( int , bound_test_case_num , BOUND ); int test_case_num = 1; if constexpr( bound_test_case_num > 1 ){ CERR( "テストケースの個数を入力してください。" ); SET_ASSERT( test_case_num , 1 , bound_test_case_num ); } REPEAT( test_case_num ){ if constexpr( bound_test_case_num > 1 ){ CERR( "testcase " , VARIABLE_FOR_REPEAT_test_case_num , ":" ); } Solve(); CERR( "" ); } } #define START_WATCH chrono::system_clock::time_point watch = chrono::system_clock::now() #define CURRENT_TIME static_cast( chrono::duration_cast( chrono::system_clock::now() - watch ).count() / 1000.0 ) #define CHECK_WATCH( TL_MS ) ( CURRENT_TIME < TL_MS - 100.0 ) #define CEXPR( LL , BOUND , VALUE ) constexpr LL BOUND = VALUE #define SET_ASSERT( A , MIN , MAX ) SET_LL( A ); ASSERT( A , MIN , MAX ) #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 FOR( VAR , INITIAL , FINAL_PLUS_ONE ) for( decldecay_t( FINAL_PLUS_ONE ) VAR = INITIAL ; VAR < FINAL_PLUS_ONE ; VAR ++ ) #define FOREQ( VAR , INITIAL , FINAL ) for( decldecay_t( FINAL ) VAR = INITIAL ; VAR <= FINAL ; VAR ++ ) #define FOREQINV( VAR , INITIAL , FINAL ) for( decldecay_t( INITIAL ) VAR = INITIAL ; VAR + 1 > FINAL ; VAR -- ) #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_ ## HOW_MANY_TIMES , 0 , HOW_MANY_TIMES ) #define SET_PRECISION( DECIMAL_DIGITS ) cout << fixed << setprecision( DECIMAL_DIGITS ) #define RETURN( ... ) COUT( __VA_ARGS__ ); return // 型のエイリアス #define decldecay_t( VAR ) decay_t template using ret_t = decltype( declval()( declval()... ) ); template using inner_t = typename T::type; using uint = unsigned int; using ll = long long; using ull = unsigned long long; using ld = long double; using lld = __float128; template using T2 = pair; template using T3 = tuple; template using T4 = tuple; using path = pair; // 入出力用 template typename V> inline auto operator>>( basic_istream& is , V& arg ) -> decltype((get<0>(arg),is))& { return is >> get<0>( arg ) >> get<1>( arg ); } template inline basic_istream& operator>>( basic_istream& is , tuple& arg ) { return is >> get<0>( arg ) >> get<1>( arg ) >> get<2>( arg ); } template inline basic_istream& operator>>( basic_istream& is , tuple& arg ) { return is >> get<0>( arg ) >> get<1>( arg ) >> get<2>( arg ) >> get<3>( arg ); } template typename V> inline auto operator<<( basic_ostream& os , const V& arg ) -> decltype((get<0>(arg),os))& { return os << get<0>( arg ) << " " << get<1>( arg ); } template inline basic_ostream& operator<<( basic_ostream& os , const tuple& arg ) { return os << get<0>( arg ) << " " << get<1>( arg ) << " " << get<2>( arg ); } template inline basic_ostream& operator<<( basic_ostream& os , const tuple& arg ) { return os << get<0>( arg ) << " " << get<1>( arg ) << " " << get<2>( arg ) << " " << get<3>( arg ); } #define DEFINITION_OF_COUT_FOR_VECTOR( V ) template inline basic_ostream& operator<<( basic_ostream& os , const V& arg ) { auto begin = arg.begin() , end = arg.end(); auto itr = begin; while( itr != end ){ ( itr == begin ? os : os << " " ) << *itr; itr++; } return os; } DEFINITION_OF_COUT_FOR_VECTOR( vector ); DEFINITION_OF_COUT_FOR_VECTOR( list ); DEFINITION_OF_COUT_FOR_VECTOR( set ); DEFINITION_OF_COUT_FOR_VECTOR( unordered_set ); inline void VariadicResize( const int& size ) {} template inline void VariadicResize( const int& size , Arg& arg , ARGS&... args ) { arg.resize( size ); VariadicResize( size , args... ); } template inline basic_istream& VariadicCin( basic_istream& is ) { return is; } template inline basic_istream& VariadicCin( basic_istream& is , Arg& arg , ARGS&... args ) { return VariadicCin( is >> arg , args... ); } template inline basic_istream& VariadicSet( basic_istream& is , const int& i ) { return is; } template inline basic_istream& VariadicSet( basic_istream& is , const int& i , Arg& arg , ARGS&... args ) { return VariadicSet( is >> arg[i] , i , args... ); } template inline basic_istream& VariadicGetline( basic_istream& is , const char& separator ) { return is; } template inline basic_istream& VariadicGetline( basic_istream& is , const char& separator , Arg& arg , ARGS&... args ) { return VariadicGetline( getline( is , arg , separator ) , separator , args... ); } template inline basic_ostream& VariadicCout( basic_ostream& os , const Arg& arg ) { return os << arg; } template inline basic_ostream& VariadicCout( basic_ostream& os , const Arg1& arg1 , const Arg2& arg2 , const ARGS&... args ) { return VariadicCout( os << arg1 << " " , arg2 , args... ); } // デバッグ用 #ifdef DEBUG inline void AlertAbort( int n ) { CERR( "abort関数が呼ばれました。assertマクロのメッセージが出力されていない場合はオーバーフローの有無を確認をしてください。" ); } #endif #define INCLUDE_LIBRARY #include __FILE__ #endif // INCLUDE_LIBRARY #endif // INCLUDE_MAIN