#ifndef INCLUDE_MODE #define INCLUDE_MODE // #define REACTIVE // #define USE_GETLINE #endif #ifdef INCLUDE_MAIN inline void Solve() { // N,Mの入力受け取り CEXPR( int , bound_N , 1e5 ); CIN_ASSERT( N , 2 , bound_N ); CEXPR( int , bound_M , 1e5 ); CIN_ASSERT( M , 1 , bound_M ); // uj,vj,hjの入力受け取り vector> e( N ); CEXPR( int , bound_h , 1e9 ); REPEAT( M ){ CIN_ASSERT( u , 1 , N ); CIN_ASSERT( v , u + 1 , N ); --u; --v; CIN_ASSERT( h , 1 , bound_h ); e[u].push_back( { v , -h } ); e[v].push_back( { u , -h } ); } // -hを辺の重みとする無向グラフの構築(好きに実装してよい) Graph graph{ N , [&]( const int& u ) -> const vector& { return e[u]; } }; // -1e9を下限としたmax演算に関するモノイドの構築(好きに実装してよい) MaxSemilattice monoid{ -bound_h }; //ダイクストラ法(好きに実装してよい) // 経路が存在しない場合の計算値は0に設定 AbstractDijkstra dijk{ graph , monoid , 0 }; int answer = - dijk.GetDistance( 0 )[N-1]; // 答えの出力 if( answer == 0 ){ RETURN( "NaN" ); } else { RETURN( 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 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 VirtualMeetSemilattice:VI PU VirtualMonoid{PU:IN U Meet(U u0,CO U& u1);};TE CL MinSemilattice:VI PU VirtualMeetSemilattice,PU PointedSet{PU:IN MinSemilattice(U infty_U);IN U Product(U u0,CO U& u1);};TE CL MaxSemilattice:VI PU VirtualMeetSemilattice,PU PointedSet{PU:IN MaxSemilattice(U zero_U);IN U Product(U u0,CO U& u1);}; TE IN U VirtualMeetSemilattice::Meet(U u0,CO U& u1){RE TH->Product(MO(u0),u1);}TE IN MinSemilattice::MinSemilattice(U infty_U):PointedSet(MO(infty_U)){}TE IN MaxSemilattice::MaxSemilattice(U zero_U):PointedSet(MO(zero_U)){}TE IN U MinSemilattice::Product(U u0,CO U& u1){RE u0 < u1?MO(u0):u1;}TE IN U MaxSemilattice::Product(U u0,CO U& u1){RE u1 < u0?MO(u0):u1;} #define DC_OF_HASH(...)struct hash<__VA_ARGS__>{IN size_t OP()(CO __VA_ARGS__& n)CO;}; 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>>; #define DF_OF_AR_FOR_MAP(MAP,OPR)TE IN MAP& OP OPR ## =(MAP& a,CO pair& v){a[v.first]OPR ## = v.second;RE a;}TE IN MAP& OP OPR ## =(MAP& a0,CO MAP& a1){for(auto&[t,u]:a1){a0[t]OPR ## = u;}RE a0;}TE IN MAP OP OPR(MAP a,CO ARG& arg){RE MO(a OPR ## = arg);} #define DF_OF_ARS_FOR_MAP(MAP)DF_OF_AR_FOR_MAP(MAP,+);DF_OF_AR_FOR_MAP(MAP,-);DF_OF_AR_FOR_MAP(MAP,*);DF_OF_AR_FOR_MAP(MAP,/);DF_OF_AR_FOR_MAP(MAP,%); TE US Map = conditional_t>,unordered_map,conditional_t,map,VO>>; DF_OF_ARS_FOR_MAP(map);DF_OF_ARS_FOR_MAP(unordered_map); TE CL VirtualGraph:VI PU UnderlyingSet{PU:VI R1 Enumeration(CRI i)= 0;IN R2 Enumeration_inv(CO T& t);TE IN R2 Enumeration_inv(CO PATH& p);IN VO Reset();VI CRI SZ()CO NE = 0;VI E& edge()NE = 0;VI ret_t Edge(CO T& t)= 0;TE IN ret_t Edge(CO PATH& p);ST IN CO T& Vertex(CO T& t)NE;TE ST IN CO T& Vertex(CO PATH& e)NE;VI R2 Enumeration_inv_Body(CO T& t)= 0;};TE CL EdgeImplimentation:VI PU VirtualGraph{PU:int m_SZ;E m_edge;IN EdgeImplimentation(CRI SZ,E edge);IN CRI SZ()CO NE;IN E& edge()NE;IN ret_t Edge(CO T& t);};TE CL Graph:PU EdgeImplimentation{PU:IN Graph(CRI SZ,E edge);IN CRI Enumeration(CRI i);TE IN Graph GetGraph(F edge)CO;IN CRI Enumeration_inv_Body(CRI t);};TE CL EnumerationGraph:PU EdgeImplimentation,ret_t,E>{PU:Enum_T m_enum_T;Enum_T_inv m_enum_T_inv;IN EnumerationGraph(CRI SZ,Enum_T enum_T,Enum_T_inv enum_T_inv,E edge);IN ret_t Enumeration(CRI i);TE IN EnumerationGraph GetGraph(F edge)CO;IN ret_t Enumeration_inv_Body(CO T& t);};TE EnumerationGraph(CRI SZ,Enum_T enum_T,Enum_T_inv enum_T_inv,E edge)-> EnumerationGraph()(0)),Enum_T,Enum_T_inv,E>;TE CL MemorisationGraph:PU EdgeImplimentation{PU:int m_LE;VE m_memory;Map m_memory_inv;IN MemorisationGraph(CRI SZ,CO T& dummy,E edge);IN T Enumeration(CRI i);IN VO Reset();TE IN MemorisationGraph GetGraph(F edge)CO;IN CRI Enumeration_inv_Body(CO T& t);}; TE IN EdgeImplimentation::EdgeImplimentation(CRI SZ,E edge):m_SZ(SZ),m_edge(MO(edge)){ST_AS(is_COructible_v && is_COructible_v && is_invocable_v);}TE IN Graph::Graph(CRI SZ,E edge):EdgeImplimentation(SZ,MO(edge)){}TE IN EnumerationGraph::EnumerationGraph(CRI SZ,Enum_T enum_T,Enum_T_inv enum_T_inv,E edge):EdgeImplimentation,ret_t,E>(SZ,MO(edge)),m_enum_T(MO(enum_T)),m_enum_T_inv(MO(enum_T_inv)){}TE IN MemorisationGraph::MemorisationGraph(CRI SZ,CO T& dummy,E edge):EdgeImplimentation(SZ,MO(edge)),m_LE(),m_memory(),m_memory_inv(){ST_AS(is_invocable_v);}TE IN CRI Graph::Enumeration(CRI i){RE i;}TE IN ret_t EnumerationGraph::Enumeration(CRI i){RE m_enum_T(i);}TE IN T MemorisationGraph::Enumeration(CRI i){AS(0 <= i && i < m_LE);RE m_memory[i];}TE IN R2 VirtualGraph::Enumeration_inv(CO T& t){RE Enumeration_inv_Body(t);}TE TE IN R2 VirtualGraph::Enumeration_inv(CO PATH& p){RE Enumeration_inv_Body(get<0>(p));}TE IN CRI Graph::Enumeration_inv_Body(CRI i){RE i;}TE IN ret_t EnumerationGraph::Enumeration_inv_Body(CO T& t){RE m_enum_T_inv(t);}TE IN CRI MemorisationGraph::Enumeration_inv_Body(CO T& t){if(m_memory_inv.count(t)== 0){AS(m_LE < TH->SZ());m_memory.push_back(t);RE m_memory_inv[t]= m_LE++;}RE m_memory_inv[t];}TE VO VirtualGraph::Reset(){}TE IN VO MemorisationGraph::Reset(){m_LE = 0;m_memory.clear();m_memory_inv.clear();}TE IN CRI EdgeImplimentation::SZ()CO NE{RE m_SZ;}TE IN E& EdgeImplimentation::edge()NE{RE m_edge;}TE IN ret_t EdgeImplimentation::Edge(CO T& t){RE m_edge(t);}TE TE IN ret_t VirtualGraph::Edge(CO PATH& p){RE Edge(get<0>(p));}TE TE IN Graph Graph::GetGraph(F edge)CO{RE Graph(TH->SZ(),MO(edge));}TE TE IN EnumerationGraph EnumerationGraph::GetGraph(F edge)CO{RE EnumerationGraph(TH->SZ(),m_enum_T,m_enum_T_inv,MO(edge));}TE TE IN MemorisationGraph MemorisationGraph::GetGraph(F edge)CO{RE MemorisationGraph(TH->SZ(),MO(edge));}TE IN CO T& VirtualGraph::Vertex(CO T& t)NE{RE t;}TE TE IN CO T& VirtualGraph::Vertex(CO PATH& e)NE{RE Vertex(get<0>(e));} #define DIJKSTRA_PREP(INITIALISE_PREV)CO U& one = m_M.One();AS(one < infty);auto&& i_start = m_G.Enumeration_inv(t_start);AS(0 <= i_start && i_start < SZ);INITIALISE_PREV; #define DIJKSTRA_BODY_1(SET_PREV)if(path_LE == -1){path_LE = SZ - 1;}weight[i_start]= one;int i = i_start;for(int num = 0;num < path_LE;num++){CO U& weight_i = weight[i];fixed[i]= true;auto&& edge_i = m_G.Edge(m_G.Enumeration(i));for(auto IT = edge_i.BE(),EN = edge_i.end();IT != EN;IT++){auto&& j = m_G.Enumeration_inv(IT->first);if(!fixed[j]){CO U& edge_ij = get<1>(*IT);U temp = m_M.Product(weight_i,edge_ij);AS(temp < infty);U& weight_j = weight[j];if(temp < weight_j){SET_PREV;weight_j = MO(temp);}}}U temp = infty;for(int j = 0;j < SZ;j++){if(!fixed[j]){U& weight_j = weight[j];if(weight_j < temp){temp = weight_j;i = j;}}}} #define DIJKSTRA_BODY_2(CHECK_FINAL,SET_PREV)AS(path_LE == -1);set> vertex{};vertex.insert(pair(weight[i_start]= one,i_start));WH(! vertex.empty()){auto BE = vertex.BE();auto[weight_i,i]= *BE;CHECK_FINAL;fixed[i]= true;vertex.erase(BE);auto&& edge_i = m_G.Edge(m_G.Enumeration(i));VE> changed_vertex{};for(auto IT = edge_i.BE(),EN = edge_i.end();IT != EN;IT++){auto&& j = m_G.Enumeration_inv(IT->first);if(!fixed[j]){CO U& edge_ij = get<1>(*IT);U temp = m_M.Product(weight_i,edge_ij);AS(temp < infty);U& weight_j = weight[j];if(temp < weight_j){if(weight_j != infty){vertex.erase(pair(weight_j,j));}SET_PREV;changed_vertex.push_back(pair(weight_j = MO(temp),j));}}}for(auto& v:changed_vertex){vertex.insert(v);}} #define DIJKSTRA_BODY(INITIALISE_PREV,CHECK_FINAL,SET_PREV)DIJKSTRA_PREP(INITIALISE_PREV);if(many_edges){DIJKSTRA_BODY_1(SET_PREV);}else{DIJKSTRA_BODY_2(CHECK_FINAL,SET_PREV);} TE CL AbstractDijkstra:PU PointedSet{PU:GRAPH& m_G;COMM_MONOID m_M;IN AbstractDijkstra(GRAPH& G,COMM_MONOID M,CO U& infty);U GetDistance(CO inner_t& t_start,CO inner_t& t_final,CO bool& many_edges = false,int path_LE = -1);VE GetDistance(CO inner_t& t_start,CO bool& many_edges = false,int path_LE = -1);VO SetDistance(VE& weight,VE& fixed,CO inner_t& t_start,CO bool& many_edges = false,int path_LE = -1);pair>> GetPath(CO inner_t& t_start,CO inner_t& t_final,CO bool& many_edges = false,int path_LE = -1);TE TY V> pair,VE>>> GetPath(CO inner_t& t_start,CO V>& t_finals,CO bool& many_edges = false,int path_LE = -1);pair,VE>>> GetPath(CO inner_t& t_start,CO bool& many_edges = false,int path_LE = -1);};TE AbstractDijkstra(GRAPH& G,COMM_MONOID M,CO U& infty)-> AbstractDijkstra,GRAPH,U,COMM_MONOID>;TE CL Dijkstra:PU AbstractDijkstra>{PU:IN Dijkstra(GRAPH& G,CRL infty = 1e18);};TE Dijkstra(GRAPH& G,CO ARGS&... args)-> Dijkstra,GRAPH>; TE IN AbstractDijkstra::AbstractDijkstra(GRAPH& G,COMM_MONOID M,CO U& infty):PointedSet(infty),m_G(G),m_M(MO(M)){}TE IN Dijkstra::Dijkstra(GRAPH& G,CRL infty):AbstractDijkstra>(G,AdditiveMonoid<>(),infty){}TE U AbstractDijkstra::GetDistance(CO inner_t& t_start,CO inner_t& t_final,CO bool& many_edges,int path_LE){CRI SZ = m_G.SZ();CO U& infty = TH->Infty();VE weight(SZ,infty);VE fixed(SZ);auto&& i_final = m_G.Enumeration_inv(t_final);DIJKSTRA_BODY(,if(i == i_final){break;},);U AN{MO(weight[i_final])};RE AN;}TE VE AbstractDijkstra::GetDistance(CO inner_t& t_start,CO bool& many_edges,int path_LE){CRI SZ = m_G.SZ();CO U& infty = TH->Infty();VE weight(SZ,infty);VE fixed(SZ);DIJKSTRA_BODY(,,);RE weight;}TE VO AbstractDijkstra::SetDistance(VE& weight,VE& fixed,CO inner_t& t_start,CO bool& many_edges,int path_LE){CRI SZ = m_G.SZ();CO U& infty = TH->Infty();AS(int(weight.SZ())== SZ);AS(int(fixed.SZ())== SZ);DIJKSTRA_BODY(,,);RE;}TE pair>> AbstractDijkstra::GetPath(CO inner_t& t_start,CO inner_t& t_final,CO bool& many_edges,int path_LE){CRI SZ = m_G.SZ();CO U& infty = TH->Infty();VE weight(SZ,infty);VE fixed(SZ);auto&& i_final = m_G.Enumeration_inv(t_final);DIJKSTRA_BODY(VE prev(SZ),if(i == i_final){break;},prev[j]= i);int i = i_final;LI> path{};path.push_back(t_final);if(weight[i]!= infty){WH(i != i_start){i = prev[i];path.push_front(m_G.Enumeration(i));}}U AN{MO(weight[i_final])};RE{MO(AN),MO(path)};}TE TE TY V>pair,VE>>> AbstractDijkstra::GetPath(CO inner_t& t_start,CO V>& t_finals,CO bool& many_edges,int path_LE){CRI SZ = m_G.SZ();CO U& infty = TH->Infty();VE weight(SZ,infty);VE fixed(SZ);DIJKSTRA_BODY(VE prev(SZ),,prev[j]= i);CO int path_SZ = t_finals.SZ();VE>> path;path.reserve(path_SZ);for(auto IT = t_finals.BE(),EN = t_finals.EN();IT != EN;IT++){LI> path_j{};CO inner_t& t_final = *IT;path_j.push_back(t_final);int i = m_G.Enumeration_inv(t_final);if(weight[i]!= infty){WH(i != i_start){i = prev[i];path_j.push_front(m_G.Enumeration(i));}}path.push_back(path_j);}RE{MO(weight),MO(path)};}TE pair,VE>>> AbstractDijkstra::GetPath(CO inner_t& t_start,CO bool& many_edges,int path_LE){CRI SZ = m_G.SZ();VE> t_finals(SZ);for(int i = 0;i < SZ;i++){t_finals[i]= i;}RE GetPath(t_start,t_finals,many_edges,path_LE);} // 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