ADDED SRM/TCO13-3A-U/1A.cpp Index: SRM/TCO13-3A-U/1A.cpp ================================================================== --- SRM/TCO13-3A-U/1A.cpp +++ SRM/TCO13-3A-U/1A.cpp @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +typedef long double LD; +typedef complex CMP; + +int bitcnt(int x) +{ + int c = 0; + for(; x; x>>=1) + c += x&1; + return c; +} + +class YetAnotherANDProblem { public: + string test(vector X, int K, vector queries) + { + string s; + for(int i=0; i& X, int K, int q) + { + int N = X.size(); + for(int mask=0; mask<(1<=2 && 3<=bc && bc<=1LL< +double start_time; string timer() + { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } +template ostream& operator<<(ostream& os, const vector& v) + { os << "{ "; + for(typename vector::const_iterator it=v.begin(); it!=v.end(); ++it) + os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } +void verify_case(const string& Expected, const string& Received) { + bool ok = (Expected == Received); + if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; + cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } +#define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); +#define END verify_case(_, YetAnotherANDProblem().test(X, K, queries));} +int main(){ + +CASE(0) + int X_[] = {10, 14, 7}; + vector X(X_, X_+sizeof(X_)/sizeof(*X_)); + int K = 1; + int queries_[] = {10, 14, 2, 4}; + vector queries(queries_, queries_+sizeof(queries_)/sizeof(*queries_)); + string _ = "+-+-"; +END +CASE(1) + int X_[] = {30, 29, 27, 23, 15}; + vector X(X_, X_+sizeof(X_)/sizeof(*X_)); + int K = 2; + int queries_[] = {28, 9, 16, 0, 12}; + vector queries(queries_, queries_+sizeof(queries_)/sizeof(*queries_)); + string _ = "-++-+"; +END +CASE(2) + int X_[] = {5, 5, 5, 5, 5}; + vector X(X_, X_+sizeof(X_)/sizeof(*X_)); + int K = 50; + int queries_[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + vector queries(queries_, queries_+sizeof(queries_)/sizeof(*queries_)); + string _ = "-----+----"; +END +CASE(3) + int X_[] = {71258, 1257, 2592588, 2885851, 999928, 123456, 59881, 99999}; + vector X(X_, X_+sizeof(X_)/sizeof(*X_)); + int K = 4; + int queries_[] = {72, 91, 10, 0, 27, 64, 8}; + vector queries(queries_, queries_+sizeof(queries_)/sizeof(*queries_)); + string _ = "+--+-++"; +END +/* +CASE(4) + int X_[] = ; + vector X(X_, X_+sizeof(X_)/sizeof(*X_)); + int K = ; + int queries_[] = ; + vector queries(queries_, queries_+sizeof(queries_)/sizeof(*queries_)); + string _ = ; +END +CASE(5) + int X_[] = ; + vector X(X_, X_+sizeof(X_)/sizeof(*X_)); + int K = ; + int queries_[] = ; + vector queries(queries_, queries_+sizeof(queries_)/sizeof(*queries_)); + string _ = ; +END +*/ +} +// END CUT HERE ADDED SRM/TCO13-3A-U/1B-U.cpp Index: SRM/TCO13-3A-U/1B-U.cpp ================================================================== --- SRM/TCO13-3A-U/1B-U.cpp +++ SRM/TCO13-3A-U/1B-U.cpp @@ -0,0 +1,293 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +typedef long long LL; +typedef long double LD; +typedef complex CMP; + +const int dy[] = {-1,+1,0,0}; +const int dx[] = {0,0,-1,+1}; + +template +class IdGen +{ + map v2id_; + vector id2v_; +public: + int v2id(const T& v) { + if( !v2id_.count(v) ) { v2id_[v] = size(); id2v_.push_back(v); } + return v2id_[v]; + } + const T& id2v(int i) const { return id2v_[i]; } + int size() const { return id2v_.size(); } +}; + +template +class MaxFlow +{ + IdGen idgen; + vector G[NV]; + Flow F[NV][NV]; + +public: + void addEdge( Vert s_, Vert t_, Flow f ) + { + const int s = idgen.v2id(s_), t = idgen.v2id(t_); + G[s].push_back(t); + G[t].push_back(s); + F[s][t] = f; + F[t][s] = 0; + } + + Flow calc( Vert s_, Vert t_ ) + { + const int S = idgen.v2id(s_), D = idgen.v2id(t_); + for( Flow total=0 ;; ) { + // Do BFS and compute the level for each node. + int LV[NV] = {0}; + vector Q(1, S); + for(int lv=1; !Q.empty(); ++lv) { + vector Q2; + for(size_t i=0; i!=Q.size(); ++i) { + const vector& ne = G[Q[i]]; + for(size_t j=0; j!=ne.size(); ++j) + if( F[Q[i]][ne[j]] && !LV[ne[j]] && ne[j]!=S ) + LV[ne[j]]=lv, Q2.push_back(ne[j]); + } + Q.swap(Q2); + } + + // Destination is now unreachable. Done. + if( !LV[D] ) + return total; + + // Iterating DFS. + bool blocked[NV] = {}; + total += dinic_dfs( S, D, LV, 0x7fffffff, blocked ); + } + } + +private: + Flow dinic_dfs( int v, int D, int LV[], Flow flow_in, bool blocked[] ) + { + Flow flow_out = 0; + for(size_t i=0; i!=G[v].size(); ++i) { + int u = G[v][i]; + if( LV[v]+1==LV[u] && F[v][u] ) { + Flow f = min(flow_in-flow_out, F[v][u]); + if( u==D || !blocked[u] && (f=dinic_dfs(u,D,LV,f,blocked))>0 ) { + F[v][u] -= f; + F[u][v] += f; + flow_out += f; + if( flow_in == flow_out ) return flow_out; + } + } + } + blocked[v] = (flow_out==0); + return flow_out; + } +}; + +class Block3Checkers { public: + int blockThem(vector board) + { + int H = board.size(); + int W = board[0].size(); + for(int y=0; y > ps, as; + for(int y=0; y > rf; + if(ok(board,as,rf)) + return 0; + for(int i=0; i& B, vector >& as, vector >& rf) + { + int H = B.size(); + int W = B[0].size(); + rf.assign(H, vector(W, 0)); + for(int i=0; i > q; + q.push(as[i]); + while(!q.empty()) { + int y = q.front().first; + int x = q.front().second; + q.pop(); + for(int d=0; d<4; ++d) { + int yy = y+dy[d]; + int xx = x+dx[d]; + if(0<=yy&&yy& B, pair S, pair D) + { + int OUT = 0, IN = 1; + typedef pair > Vert; + MaxFlow* mf = new MaxFlow; + int H = B.size(); + int W = B[0].size(); + for(int y=0; y p(y,x); + for(int d=0; d<4; ++d) { + int xx = x+dx[d]; + int yy = y+dy[d]; + if(0<=xx&&xxaddEdge(make_pair(OUT, p), make_pair(IN, make_pair(yy,xx)), 1); + } + if(p!=S && p!=D) + mf->addEdge(make_pair(IN, p), make_pair(OUT, p), 1); + } + int m = mf->calc(make_pair(OUT,S), make_pair(IN,D)); + delete mf; + return m; + } +}; + +// BEGIN CUT HERE +#include +double start_time; string timer() + { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } +template ostream& operator<<(ostream& os, const vector& v) + { os << "{ "; + for(typename vector::const_iterator it=v.begin(); it!=v.end(); ++it) + os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } +void verify_case(const int& Expected, const int& Received) { + bool ok = (Expected == Received); + if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; + cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } +#define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); +#define END verify_case(_, Block3Checkers().blockThem(board));} +int main(){ + +CASE(0) + string board_[] = {"A......A", + "...N.N..", + ".NNN.NN.", + "NNNN.N.N", + "N.NN.NNN", + ".NNN.NNN", + "NNN...NN", + ".NN.A..N"}; + vector board(board_, board_+sizeof(board_)/sizeof(*board_)); + int _ = 1; +END +CASE(1) + string board_[] = {".....A", + "......", + "......", + "NNNNNN", + "A.....", + "A....."}; + vector board(board_, board_+sizeof(board_)/sizeof(*board_)); + int _ = 100; +END +CASE(2) + string board_[] = {"A.N", + "NNA", + "AN."}; + vector board(board_, board_+sizeof(board_)/sizeof(*board_)); + int _ = 0; +END +CASE(3) + string board_[] = {"......NA", + ".NNNN.N.", + ".N......", + "....NNNN", + "........", + ".N..NNN.", + "......N.", + "A.N....A"} +; + vector board(board_, board_+sizeof(board_)/sizeof(*board_)); + int _ = 3; +END +/* +CASE(4) + string board_[] = ; + vector board(board_, board_+sizeof(board_)/sizeof(*board_)); + int _ = ; +END +CASE(5) + string board_[] = ; + vector board(board_, board_+sizeof(board_)/sizeof(*board_)); + int _ = ; +END +*/ +} +// END CUT HERE