f6764c7ea7 2011-12-17 kinaba: #include <iostream> f6764c7ea7 2011-12-17 kinaba: #include <sstream> f6764c7ea7 2011-12-17 kinaba: #include <iomanip> f6764c7ea7 2011-12-17 kinaba: #include <vector> f6764c7ea7 2011-12-17 kinaba: #include <string> f6764c7ea7 2011-12-17 kinaba: #include <map> f6764c7ea7 2011-12-17 kinaba: #include <set> f6764c7ea7 2011-12-17 kinaba: #include <algorithm> f6764c7ea7 2011-12-17 kinaba: #include <numeric> f6764c7ea7 2011-12-17 kinaba: #include <iterator> f6764c7ea7 2011-12-17 kinaba: #include <functional> f6764c7ea7 2011-12-17 kinaba: #include <complex> f6764c7ea7 2011-12-17 kinaba: #include <queue> f6764c7ea7 2011-12-17 kinaba: #include <stack> f6764c7ea7 2011-12-17 kinaba: #include <cmath> f6764c7ea7 2011-12-17 kinaba: #include <cassert> f6764c7ea7 2011-12-17 kinaba: #include <cstring> f6764c7ea7 2011-12-17 kinaba: #ifdef __GNUC__ f6764c7ea7 2011-12-17 kinaba: #include <ext/hash_map> f6764c7ea7 2011-12-17 kinaba: #define unordered_map __gnu_cxx::hash_map f6764c7ea7 2011-12-17 kinaba: #else f6764c7ea7 2011-12-17 kinaba: #include <unordered_map> f6764c7ea7 2011-12-17 kinaba: #endif f6764c7ea7 2011-12-17 kinaba: using namespace std; f6764c7ea7 2011-12-17 kinaba: typedef long long LL; f6764c7ea7 2011-12-17 kinaba: typedef complex<double> CMP; f6764c7ea7 2011-12-17 kinaba: static const int INF = 0x3fffffff; f6764c7ea7 2011-12-17 kinaba: f6764c7ea7 2011-12-17 kinaba: class PrimeCompositeGame { public: f6764c7ea7 2011-12-17 kinaba: int theOutcome(int N, int K) f6764c7ea7 2011-12-17 kinaba: { f6764c7ea7 2011-12-17 kinaba: enum {P, C}; f6764c7ea7 2011-12-17 kinaba: f6764c7ea7 2011-12-17 kinaba: // sieve f6764c7ea7 2011-12-17 kinaba: vector< vector<bool> > is(2, vector<bool>(N+1, true)); f6764c7ea7 2011-12-17 kinaba: is[P][0] = is[C][0] = is[P][1] = is[C][1] = false; f6764c7ea7 2011-12-17 kinaba: for(int p=2; p<=N; ++p) { f6764c7ea7 2011-12-17 kinaba: if( is[P][p] ) f6764c7ea7 2011-12-17 kinaba: for(int q=p+p; q<=N; q+=p) f6764c7ea7 2011-12-17 kinaba: is[P][q] = false; f6764c7ea7 2011-12-17 kinaba: is[C][p] = !is[P][p]; f6764c7ea7 2011-12-17 kinaba: } f6764c7ea7 2011-12-17 kinaba: f6764c7ea7 2011-12-17 kinaba: vector< vector<int> > score(2, vector<int>(N+1)); f6764c7ea7 2011-12-17 kinaba: multiset<int> lastK[2]; f6764c7ea7 2011-12-17 kinaba: for(int t=0; t<=N; ++t) { f6764c7ea7 2011-12-17 kinaba: for(int me=0; me<2; ++me) f6764c7ea7 2011-12-17 kinaba: if( lastK[1^me].empty() ) // no valid move. immediately lose. f6764c7ea7 2011-12-17 kinaba: score[me][t] = 0; f6764c7ea7 2011-12-17 kinaba: else if( *lastK[1^me].begin() > 0 ) // all move make opponent win. take the longest. f6764c7ea7 2011-12-17 kinaba: score[me][t] = - (1 + *lastK[1^me].rbegin()); f6764c7ea7 2011-12-17 kinaba: else // I can win. take the shortest. f6764c7ea7 2011-12-17 kinaba: score[me][t] = (1 + abs(*--lastK[1^me].lower_bound(1))); f6764c7ea7 2011-12-17 kinaba: // maintain last K scores. f6764c7ea7 2011-12-17 kinaba: for(int me=0; me<2; ++me) { f6764c7ea7 2011-12-17 kinaba: if( is[1^me][t] ) f6764c7ea7 2011-12-17 kinaba: lastK[me].insert( score[me][t] ); f6764c7ea7 2011-12-17 kinaba: if( t-K>=0 && is[1^me][t-K] ) f6764c7ea7 2011-12-17 kinaba: lastK[me].erase(lastK[me].find(score[me][t-K])); f6764c7ea7 2011-12-17 kinaba: } f6764c7ea7 2011-12-17 kinaba: } f6764c7ea7 2011-12-17 kinaba: return score[P][N]; f6764c7ea7 2011-12-17 kinaba: } f6764c7ea7 2011-12-17 kinaba: }; f6764c7ea7 2011-12-17 kinaba: f6764c7ea7 2011-12-17 kinaba: // BEGIN CUT HERE f6764c7ea7 2011-12-17 kinaba: #include <ctime> f6764c7ea7 2011-12-17 kinaba: double start_time; string timer() f6764c7ea7 2011-12-17 kinaba: { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } f6764c7ea7 2011-12-17 kinaba: template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) f6764c7ea7 2011-12-17 kinaba: { os << "{ "; f6764c7ea7 2011-12-17 kinaba: for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it) f6764c7ea7 2011-12-17 kinaba: os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } f6764c7ea7 2011-12-17 kinaba: void verify_case(const int& Expected, const int& Received) { f6764c7ea7 2011-12-17 kinaba: bool ok = (Expected == Received); f6764c7ea7 2011-12-17 kinaba: if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; f6764c7ea7 2011-12-17 kinaba: cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } f6764c7ea7 2011-12-17 kinaba: #define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); f6764c7ea7 2011-12-17 kinaba: #define END verify_case(_, PrimeCompositeGame().theOutcome(N, K));} f6764c7ea7 2011-12-17 kinaba: int main(){ f6764c7ea7 2011-12-17 kinaba: f6764c7ea7 2011-12-17 kinaba: CASE(0) f6764c7ea7 2011-12-17 kinaba: int N = 3; f6764c7ea7 2011-12-17 kinaba: int K = 2; f6764c7ea7 2011-12-17 kinaba: int _ = 1; f6764c7ea7 2011-12-17 kinaba: END f6764c7ea7 2011-12-17 kinaba: CASE(1) f6764c7ea7 2011-12-17 kinaba: int N = 58; f6764c7ea7 2011-12-17 kinaba: int K = 1; f6764c7ea7 2011-12-17 kinaba: int _ = 0; f6764c7ea7 2011-12-17 kinaba: END f6764c7ea7 2011-12-17 kinaba: CASE(2) f6764c7ea7 2011-12-17 kinaba: int N = 30; f6764c7ea7 2011-12-17 kinaba: int K = 3; f6764c7ea7 2011-12-17 kinaba: int _ = -2; f6764c7ea7 2011-12-17 kinaba: END f6764c7ea7 2011-12-17 kinaba: CASE(3) f6764c7ea7 2011-12-17 kinaba: int N = 6; f6764c7ea7 2011-12-17 kinaba: int K = 3; f6764c7ea7 2011-12-17 kinaba: int _ = 1; f6764c7ea7 2011-12-17 kinaba: END f6764c7ea7 2011-12-17 kinaba: CASE(4) f6764c7ea7 2011-12-17 kinaba: int N = 526; f6764c7ea7 2011-12-17 kinaba: int K = 58; f6764c7ea7 2011-12-17 kinaba: int _ = 19; f6764c7ea7 2011-12-17 kinaba: END f6764c7ea7 2011-12-17 kinaba: CASE(5) f6764c7ea7 2011-12-17 kinaba: int N = 474747; f6764c7ea7 2011-12-17 kinaba: int K = 474747; f6764c7ea7 2011-12-17 kinaba: int _ = 1; f6764c7ea7 2011-12-17 kinaba: END f6764c7ea7 2011-12-17 kinaba: /* f6764c7ea7 2011-12-17 kinaba: CASE(6) f6764c7ea7 2011-12-17 kinaba: int N = ; f6764c7ea7 2011-12-17 kinaba: int K = ; f6764c7ea7 2011-12-17 kinaba: int _ = ; f6764c7ea7 2011-12-17 kinaba: END f6764c7ea7 2011-12-17 kinaba: */ f6764c7ea7 2011-12-17 kinaba: } f6764c7ea7 2011-12-17 kinaba: // END CUT HERE