結果
問題 | No.2829 GCD Divination |
ユーザー | 👑 p-adic |
提出日時 | 2024-06-20 14:43:32 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 28 ms / 2,000 ms |
コード長 | 22,064 bytes |
コンパイル時間 | 3,163 ms |
コンパイル使用メモリ | 229,988 KB |
実行使用メモリ | 81,776 KB |
最終ジャッジ日時 | 2024-06-20 23:01:50 |
合計ジャッジ時間 | 4,952 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 23 ms
81,632 KB |
testcase_01 | AC | 21 ms
81,428 KB |
testcase_02 | AC | 23 ms
81,496 KB |
testcase_03 | AC | 21 ms
81,616 KB |
testcase_04 | AC | 21 ms
81,776 KB |
testcase_05 | AC | 28 ms
81,492 KB |
testcase_06 | AC | 28 ms
81,612 KB |
testcase_07 | AC | 28 ms
81,660 KB |
testcase_08 | AC | 28 ms
81,596 KB |
testcase_09 | AC | 25 ms
81,612 KB |
testcase_10 | AC | 23 ms
81,700 KB |
testcase_11 | AC | 20 ms
81,628 KB |
testcase_12 | AC | 22 ms
81,776 KB |
testcase_13 | AC | 21 ms
81,596 KB |
testcase_14 | AC | 21 ms
81,552 KB |
testcase_15 | AC | 22 ms
81,608 KB |
testcase_16 | AC | 21 ms
81,436 KB |
testcase_17 | AC | 22 ms
81,604 KB |
testcase_18 | AC | 22 ms
81,660 KB |
testcase_19 | AC | 22 ms
81,600 KB |
testcase_20 | AC | 22 ms
81,492 KB |
testcase_21 | AC | 22 ms
81,604 KB |
testcase_22 | AC | 21 ms
81,628 KB |
testcase_23 | AC | 22 ms
81,496 KB |
testcase_24 | AC | 23 ms
81,660 KB |
testcase_25 | AC | 22 ms
81,612 KB |
testcase_26 | AC | 23 ms
81,432 KB |
testcase_27 | AC | 22 ms
81,604 KB |
testcase_28 | AC | 21 ms
81,440 KB |
testcase_29 | AC | 22 ms
81,440 KB |
testcase_30 | AC | 22 ms
81,496 KB |
testcase_31 | AC | 22 ms
81,664 KB |
testcase_32 | AC | 21 ms
81,436 KB |
testcase_33 | AC | 22 ms
81,632 KB |
testcase_34 | AC | 22 ms
81,608 KB |
ソースコード
// 入力制約チェック #ifndef INCLUDE_MODE #define INCLUDE_MODE // #define REACTIVE // #define USE_GETLINE #endif #ifdef INCLUDE_MAIN constexpr PrimeEnumeration<int,3163> pe{}; vector<double> memory( 10000001 , -1.0 ); double f( const int& N ){ if( memory[N] < -0.5 ){ memory[N] = N; RUN( EnumerateDivisor(pe,N) , d ){ d > 1 ? memory[N] += f( N / d ) * get<0>( EulerFunction( pe , d ) ) : memory[N]; }; memory[N] /= N - 1 ; } return memory[N]; } inline void Solve() { CEXPR( int , bound_N , 1e7 ); CIN_ASSERT( N , 1 , bound_N ); memory[1] = 0.0; SET_PRECISION( 6 ); RETURN( f( N ) ); } 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<char,Traits> #define OS basic_ostream<char,Traits> #define ST_AS static_assert #define reMO_CO remove_const #define is_COructible_v is_constructible_v #define rBE rbegin #define reSZ resize #ifdef DEBUG #include "c:/Users/user/Documents/Programming/Mathematics/Arithmetic/Prime/Divisor/a_Body.hpp" #else // nの素因数分解:PrimeFactorisation(CO PrimeEnumeration<INT1,val_limit,LE_max>& pe,CO INT2& n) // nの約数数え上げ:CountDivisor(CO PrimeEnumeration<INT1,val_limit,LE_max>& pe,INT n) // nの約数辞書順列挙1:EnumerateDivisor(CO PrimeEnumeration<INT1,val_limit,LE_max>& pe,INT n) // nの約数辞書順列挙2:EnumerateDivisor(CO LeastDivisor<INT,val_limit>& ld,INT n) // SZ_max未満の数の約数全列挙:TotalEnumerateDivisor(CRI SZ) TE <TY INT,INT val_limit,int LE_max = val_limit>CL PrimeEnumeration{PU:bool m_is_composite[val_limit];INT m_val[LE_max];int m_LE;CE PrimeEnumeration();IN CO INT& OP[](CRI i)CO;CE CO INT& Get(CRI i)CO;CE CO bool& IsComposite(CRI n)CO;CE CRI LE()CO NE;}; TE <TY INT,INT val_limit,int LE_max> CE PrimeEnumeration<INT,val_limit,LE_max>::PrimeEnumeration():m_is_composite(),m_val(),m_LE(0){for(INT i = 2;i < val_limit;i++){if(! m_is_composite[i]){if(i <=(val_limit - 1)/ i){for(INT j = i * i;j < val_limit;j += i){m_is_composite[j]= true;}}m_val[m_LE++]= i;if(m_LE >= LE_max){break;}}}}TE <TY INT,INT val_limit,int LE_max> IN CO INT& PrimeEnumeration<INT,val_limit,LE_max>::OP[](CRI i)CO{AS(0 <= i && i < m_LE);RE m_val[i];}TE <TY INT,INT val_limit,int LE_max> CE CO INT& PrimeEnumeration<INT,val_limit,LE_max>::Get(CRI i)CO{RE m_val[i];}TE <TY INT,INT val_limit,int LE_max> CE CO bool& PrimeEnumeration<INT,val_limit,LE_max>::IsComposite(CRI n)CO{RE m_is_composite[n];}TE <TY INT,INT val_limit,int LE_max> CE CRI PrimeEnumeration<INT,val_limit,LE_max>::LE()CO NE{RE m_LE;} TE <TY INT1,INT1 val_limit,int LE_max,TY INT2>pair<VE<INT1>,VE<int>> PrimeFactorisation(CO PrimeEnumeration<INT1,val_limit,LE_max>& pe,INT2 n){VE<INT1> P{};VE<int> E{};CRI LE = pe.LE();for(int i = 0;i < LE;i++){CO INT1& p = pe[i];if(n % p == 0){int e = 1;WH((n /= p)% p == 0){e++;}P.push_back(p);E.push_back(e);}else if(n / p < p){break;}}if(n != 1){P.push_back(n);E.push_back(1);}RE{MO(P),MO(E)};} TE <TY INT,INT val_limit>CL LeastDivisor{PU:INT m_val[val_limit];CE LeastDivisor()NE;IN CO INT& OP[](CRI i)CO;CE CO INT& Get(CRI i)CO;}; TE <TY INT,INT val_limit> CE LeastDivisor<INT,val_limit>::LeastDivisor()NE:m_val{}{for(int d = 2;d < val_limit;d++){if(m_val[d]== 0){for(int n = d;n < val_limit;n += d){m_val[n]== 0?m_val[n]= d:d;}}}}TE <TY INT,INT val_limit> IN CO INT& LeastDivisor<INT,val_limit>::OP[](CRI i)CO{AS(0 <= i && i < val_limit);RE m_val[i];}TE <TY INT,INT val_limit> CE CO INT& LeastDivisor<INT,val_limit>::Get(CRI i)CO{RE m_val[i];} TE <TY INT> INT CountDivisorBody(VE<int>& E)NE{CO int LE = E.SZ();INT AN = 1;for(int i = 0;i < LE;i++){AN *= ++E[i];}RE AN;}TE <TY INT>INT CountDivisor(INT n)NE{auto[P,E]= PrimeFactorisation(MO(n));RE CountDivisorBody<INT>(E);}TE <TY INT,TY PE>INT CountDivisor(CO PE& pe,INT n)NE{auto[P,E]= PrimeFactorisation(pe,MO(n));RE CountDivisorBody<INT>(E);}TE <TY INT> VE<INT> EnumerateDivisorBody(CO VE<INT>& P,VE<int>& E){CO int LE = P.SZ();VE AN(CountDivisorBody<INT>(E),1);int SZ = 1;for(int i = 0;i < LE;i++){auto& P_i = P[i];auto& E_i = E[i];INT q = 1;int j_shift = 0;for(int e = 1;e < E_i;e++){q *= P_i;j_shift += SZ;for(int j = 0;j < SZ;j++){AN[j + j_shift]= AN[j]* q;}}SZ *= E_i;}RE AN;}TE <TY INT>VE<INT> EnumerateDivisor(INT n)NE{auto[P,E]= PrimeFactorisation(MO(n));RE EnumerateDivisorBody(P,E);}TE <TY INT1,INT1 val_limit,int LE_max,TY INT2>VE<INT2> EnumerateDivisor(CO PrimeEnumeration<INT1,val_limit,LE_max>& pe,INT2 n){auto[P,E]= PrimeFactorisation(pe,MO(n));RE EnumerateDivisorBody(P,E);}TE <TY INT1,INT1 val_limit,TY INT2>VE<INT2> EnumerateDivisor(CO LeastDivisor<INT1,val_limit>& ld,INT2 n){VE<INT2> P{};VE<int> E{};WH(n > 1){auto& p = ld[n];int e = 1;WH((n /= p)% p == 0){e++;}P.push_back(p);E.push_back(e);}RE EnumerateDivisorBody(P,E);}TE <TY INT>VE<VE<INT>> TotalEnumerateDivisor(CO INT& SZ)NE{VE<VE<INT>> AN(SZ);for(INT d = 1;d < SZ;d++){for(INT n = 0;n < SZ;n += d){AN[n].push_back(d);}}RE AN;} #endif #ifdef DEBUG #include "c:/Users/user/Documents/Programming/Mathematics/Arithmetic/Mod/Function/Euler/a_Body.hpp" #else // nのオイラー関数値:EulerFunction(CO PrimeEnumeration<INT1,val_limit,LE_max>& prime,CO INT2& n); // n_max以下のnのオイラー関数値:TotalEulerFunction(CO PrimeEnumeration<INT1,val_limit,LE_max>& prime,CO INT2& n_max); // val_limitは(nの上限の平方根+1)以上に設定。 // TE <TY INT,INT val_limit,int LE_max = val_limit>CL PrimeEnumeration{PU:bool m_is_composite[val_limit];INT m_val[LE_max];int m_LE;CE PrimeEnumeration();IN CO INT& OP[](CRI i)CO;CE CO INT& Get(CRI i)CO;CE CO bool& IsComposite(CRI n)CO;CE CRI LE()CO NE;}; // TE <TY INT,INT val_limit,int LE_max> CE PrimeEnumeration<INT,val_limit,LE_max>::PrimeEnumeration():m_is_composite(),m_val(),m_LE(0){for(INT i = 2;i < val_limit;i++){if(! m_is_composite[i]){if(i <=(val_limit - 1)/ i){for(INT j = i * i;j < val_limit;j += i){m_is_composite[j]= true;}}m_val[m_LE++]= i;if(m_LE >= LE_max){break;}}}}TE <TY INT,INT val_limit,int LE_max> IN CO INT& PrimeEnumeration<INT,val_limit,LE_max>::OP[](CRI i)CO{AS(0 <= i && i < m_LE);RE m_val[i];}TE <TY INT,INT val_limit,int LE_max> CE CO INT& PrimeEnumeration<INT,val_limit,LE_max>::Get(CRI i)CO{RE m_val[i];}TE <TY INT,INT val_limit,int LE_max> CE CO bool& PrimeEnumeration<INT,val_limit,LE_max>::IsComposite(CRI n)CO{RE m_is_composite[n];}TE <TY INT,INT val_limit,int LE_max> CE CRI PrimeEnumeration<INT,val_limit,LE_max>::LE()CO NE{RE m_LE;} // TE <TY INT1,INT1 val_limit,int LE_max,TY INT2>pair<VE<INT1>,VE<int>> PrimeFactorisation(CO PrimeEnumeration<INT1,val_limit,LE_max>& pe,INT2 n){VE<INT1> P{};VE<int> E{};CRI LE = pe.LE();for(int i = 0;i < LE;i++){CO INT1& p = pe[i];if(n % p == 0){int e = 1;WH((n /= p)% p == 0){e++;}P.push_back(p);E.push_back(e);}else if(n / p < p){break;}}if(n != 1){P.push_back(n);E.push_back(1);}RE{MO(P),MO(E)};}TE <TY INT1,INT1 val_limit,int LE_max,TY INT2>tuple<VE<INT1>,VE<int>,VE<INT2>> PrimePWFactorisation(CO PrimeEnumeration<INT1,val_limit,LE_max>& pe,INT2 n){VE<INT1> P{};VE<int> E{};VE<INT2> Q{};CRI LE = pe.LE();for(int i = 0;i < LE;i++){CO INT1& p = pe[i];if(n % p == 0){int e = 1;INT2 q = p;WH((n /= p)% p == 0){e++;q *= p;}P.push_back(p);E.push_back(e);Q.push_back(q);}else if(n / p < p){break;}}if(n != 1){P.push_back(n);E.push_back(1);Q.push_back(n);}RE{MO(P),MO(E),MO(Q)};} TE <TY PF,TY INT>tuple<INT,VE<INT>,VE<int>> EulerFunction_Body(PF pf,CO INT& n){auto[P,E]= pf(n);INT AN = n;for(auto& p:P){AN -= AN / p;}RE{AN,MO(P),MO(E)};}TE <TY INT1,INT1 val_limit,int LE_max,TY INT2> IN tuple<INT2,VE<INT1>,VE<int>> EulerFunction(CO PrimeEnumeration<INT1,val_limit,LE_max>& pe,CO INT2& n){RE EulerFunction_Body([&](CRI i){RE PrimeFactorisation(pe,i);},n);}TE <TY INT1,INT1 val_limit,int LE_max,int SZ,TY INT2>VE<INT2> TotalEulerFunction(CO PrimeEnumeration<INT1,val_limit,LE_max>& pe,CO INT2& n_max){VE<INT2> AN(n_max + 1);for(INT2 n = 1;n <= n_max;n++){AN[n]= n;}auto quotient = AN;CRI LE = pe.LE();for(int i = 0;i < LE;i++){CO INT2& p_i = pe[i];INT2 n = 0;WH((n += p_i)<= n_max){INT2& AN_n = AN[n];INT2& quotient_n = quotient[n];AN_n -= AN_n / p_i;WH((quotient_n /= p_i)% p_i == 0){}}}for(INT2 n = val_limit;n <= n_max;n++){CO INT2& quotient_n = quotient[n];if(quotient_n != 1){INT2& AN_n = AN[n];AN_n -= AN_n / quotient_n;}}RE AN;} #endif // 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<LL> __VA_ARGS__; SET_A( I , N , __VA_ARGS__ ); #define CIN_AA( LL , I0 , N0 , I1 , N1 , VAR ) VE<VE<LL>> VAR( N0 + I0 ); FOR( VARIABLE_FOR_CIN_AA , 0 , N0 ){ SET_A( I1 , N1 , VAR[VARIABLE_FOR_CIN_AA + I0] ); } #endif #include <bits/stdc++.h> 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( "" ); } CHECK_REDUNDANT_INPUT; } #define START_WATCH chrono::system_clock::time_point watch = chrono::system_clock::now() #define CURRENT_TIME static_cast<double>( chrono::duration_cast<chrono::microseconds>( 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<decldecay_t( MAX )> 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<decldecay_t( MAX )>( 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<decltype( VAR )> template <typename F , typename...Args> using ret_t = decltype( declval<F>()( declval<Args>()... ) ); template <typename T> 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 <typename INT> using T2 = pair<INT,INT>; template <typename INT> using T3 = tuple<INT,INT,INT>; template <typename INT> using T4 = tuple<INT,INT,INT,INT>; using path = pair<int,ll>; // 入出力用 template <class Traits , typename T , typename U , template <typename...> typename V> inline auto operator>>( basic_istream<char,Traits>& is , V<T,U>& arg ) -> decltype((get<0>(arg),is))& { return is >> get<0>( arg ) >> get<1>( arg ); } template <class Traits , typename T , typename U , typename V> inline basic_istream<char,Traits>& operator>>( basic_istream<char,Traits>& is , tuple<T,U,V>& arg ) { return is >> get<0>( arg ) >> get<1>( arg ) >> get<2>( arg ); } template <class Traits , typename T , typename U , typename V , typename W> inline basic_istream<char,Traits>& operator>>( basic_istream<char,Traits>& is , tuple<T,U,V,W>& arg ) { return is >> get<0>( arg ) >> get<1>( arg ) >> get<2>( arg ) >> get<3>( arg ); } template <class Traits , typename T , typename U , template <typename...> typename V> inline auto operator<<( basic_ostream<char,Traits>& os , const V<T,U>& arg ) -> decltype((get<0>(arg),os))& { return os << get<0>( arg ) << " " << get<1>( arg ); } template <class Traits , typename T , typename U , typename V> inline basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os , const tuple<T,U,V>& arg ) { return os << get<0>( arg ) << " " << get<1>( arg ) << " " << get<2>( arg ); } template <class Traits , typename T , typename U , typename V , typename W> inline basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os , const tuple<T,U,V,W>& arg ) { return os << get<0>( arg ) << " " << get<1>( arg ) << " " << get<2>( arg ) << " " << get<3>( arg ); } #define DEFINITION_OF_COUT_FOR_VECTOR( V ) template <class Traits , typename Arg> inline basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os , const V<Arg>& 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 <typename Arg , typename... ARGS> inline void VariadicResize( const int& size , Arg& arg , ARGS&... args ) { arg.resize( size ); VariadicResize( size , args... ); } template <class Traits> inline basic_istream<char,Traits>& VariadicCin( basic_istream<char,Traits>& is ) { return is; } template <class Traits , typename Arg , typename... ARGS> inline basic_istream<char,Traits>& VariadicCin( basic_istream<char,Traits>& is , Arg& arg , ARGS&... args ) { return VariadicCin( is >> arg , args... ); } template <class Traits> inline basic_istream<char,Traits>& VariadicSet( basic_istream<char,Traits>& is , const int& i ) { return is; } template <class Traits , typename Arg , typename... ARGS> inline basic_istream<char,Traits>& VariadicSet( basic_istream<char,Traits>& is , const int& i , Arg& arg , ARGS&... args ) { return VariadicSet( is >> arg[i] , i , args... ); } template <class Traits> inline basic_istream<char,Traits>& VariadicGetline( basic_istream<char,Traits>& is , const char& separator ) { return is; } template <class Traits , typename Arg , typename... ARGS> inline basic_istream<char,Traits>& VariadicGetline( basic_istream<char,Traits>& is , const char& separator , Arg& arg , ARGS&... args ) { return VariadicGetline( getline( is , arg , separator ) , separator , args... ); } template <class Traits , typename Arg> inline basic_ostream<char,Traits>& VariadicCout( basic_ostream<char,Traits>& os , const Arg& arg ) { return os << arg; } template <class Traits , typename Arg1 , typename Arg2 , typename... ARGS> inline basic_ostream<char,Traits>& VariadicCout( basic_ostream<char,Traits>& 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 // 入力フォーマットチェック用 // 1行中の変数の個数をSEPARATOR区切りで確認 #define GETLINE_COUNT( S , VARIABLE_NUMBER , SEPARATOR ) GETLINE( S ); int VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S = 0; int VARIABLE_FOR_SIZE_FOR_GETLINE_FOR_ ## S = S.size(); { int size = S.size(); int count = 0; for( int i = 0 ; i < size ; i++ ){ if( S[i] == SEPARATOR ){ count++; } } assert( count + 1 == VARIABLE_NUMBER ); } // 余計な入力の有無を確認 #ifdef DEBUG #define CHECK_REDUNDANT_INPUT #else #ifdef USE_GETLINE #define CHECK_REDUNDANT_INPUT string VARIABLE_FOR_CHECK_REDUNDANT_INPUT = ""; getline( cin , VARIABLE_FOR_CHECK_REDUNDANT_INPUT ); assert( VARIABLE_FOR_CHECK_REDUNDANT_INPUT == "" ); assert( ! cin ) #else #define CHECK_REDUNDANT_INPUT string VARIABLE_FOR_CHECK_REDUNDANT_INPUT = ""; cin >> VARIABLE_FOR_CHECK_REDUNDANT_INPUT; assert( VARIABLE_FOR_CHECK_REDUNDANT_INPUT == "" ); assert( ! cin ) #endif #endif // |N| <= BOUNDを満たすNをSから構築 #define STOI( S , N , BOUND ) decldecay_t( BOUND ) N = 0; { bool VARIABLE_FOR_POSITIVITY_FOR_GETLINE = true; assert( VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S < VARIABLE_FOR_SIZE_FOR_GETLINE_FOR_ ## S ); if( S.substr( VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S , 1 ) == "-" ){ VARIABLE_FOR_POSITIVITY_FOR_GETLINE = false; VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S ++; assert( VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S < VARIABLE_FOR_SIZE_FOR_GETLINE_FOR_ ## S ); } assert( S.substr( VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S , 1 ) != " " ); string VARIABLE_FOR_LETTER_FOR_GETLINE{}; int VARIABLE_FOR_DIGIT_FOR_GETLINE{}; while( VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S < VARIABLE_FOR_SIZE_FOR_GETLINE_FOR_ ## S ? ( VARIABLE_FOR_LETTER_FOR_GETLINE = S.substr( VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S , 1 ) ) != " " : false ){ VARIABLE_FOR_DIGIT_FOR_GETLINE = stoi( VARIABLE_FOR_LETTER_FOR_GETLINE ); assert( N < BOUND / 10 ? true : N == BOUND / 10 && VARIABLE_FOR_DIGIT_FOR_GETLINE <= BOUND % 10 ); N = N * 10 + VARIABLE_FOR_DIGIT_FOR_GETLINE; VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S ++; } if( ! VARIABLE_FOR_POSITIVITY_FOR_GETLINE ){ N *= -1; } if( VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S < VARIABLE_FOR_SIZE_FOR_GETLINE_FOR_ ## S ){ VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S ++; } } #define STOI_A( S , I , N , A , BOUND ) vector<decldecay_t( BOUND )> A( N + I ); FOR( VARIABLE_FOR_STOI_A , 0 , N ){ STOI( S , A ##_VARIABLE_FOR_STOI_A , BOUND ); A[VARIABLE_FOR_STOI_A + I] = A ##_VARIABLE_FOR_STOI_A; } // SをSEPARATORで区切りTを構築 #define SEPARATE( S , T , SEPARATOR ) string T{}; { assert( VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S < VARIABLE_FOR_SIZE_FOR_GETLINE_FOR_ ## S ); int VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S_prev = VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S; assert( S.substr( VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S , 1 ) != SEPARATOR ); string VARIABLE_FOR_LETTER_FOR_GETLINE{}; while( VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S < VARIABLE_FOR_SIZE_FOR_GETLINE_FOR_ ## S ? ( VARIABLE_FOR_LETTER_FOR_GETLINE = S.substr( VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S , 1 ) ) != SEPARATOR : false ){ VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S ++; } T = S.substr( VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S_prev , VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S - VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S_prev ); if( VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S < VARIABLE_FOR_SIZE_FOR_GETLINE_FOR_ ## S ){ VARIABLE_FOR_INDEX_FOR_GETLINE_FOR_ ## S ++; } } #define INCLUDE_LIBRARY #include __FILE__ #endif // INCLUDE_LIBRARY #endif // INCLUDE_MAIN