#include #include #include #include #include #include using namespace std ; double walltime() { struct timeval tv ; gettimeofday(&tv, 0) ; return tv.tv_sec + 0.000001 * tv.tv_usec ; } int bc(int v) { int r = 0 ; while (v) { r++ ; v &= v-1 ; } return r ; } int calcparity(const string &s) { int seen = 0 ; int p = 0 ; for (auto c : s) { c -= 'a' ; p += bc(((1< &w, map &back, vector > &e) { int n = w.size() ; e.clear() ; e.resize(n) ; back.clear() ; for (int i=0; i<(int)w.size(); i++) back[w[i]] = i ; for (int i=0; i<(int)w.size(); i++) { string s = w[i] ; for (int j=0; j<(int)s.size(); j++) for (int k=0; ksecond) ; swap(s[j], s[k]) ; } } } int main(int argc, char *argv[]) { srand48(time(0)) ; double start = walltime() ; int verbose = (argc > 1) ; int n ; cin >> n ; vector w(n) ; for (auto &v : w) cin >> v ; int r = 0 ; map back ; vector > e ; setup(w, back, e) ; int zerov = 0 ; for (int trial=0; walltime()-start < 0.9; trial++) { int wn = w[0].size() ; vector heads(wn*(wn-1)/2+1) ; for (auto &v : heads) { v.i = -1 ; v.l = &v ; v.r = &v ; } vector nodes(n) ; vector cec(n) ; vector ing(n), outg(n), unsure(n) ; for (auto &v : unsure) v = 1 ; for (int i=0; il = &nodes[i] ; heads[ec].r = &nodes[i] ; } int toting = 0 ; while (1) { int at = 0 ; while (at < (int)heads.size() && heads[at].r == &heads[at]) at++ ; if (at >= (int)heads.size() || (at >= 2 && trial == 0)) break ; toting++ ; link *lnk = heads[at].r ; int s = lnk->i ; // if (verbose) cout << "Including " << w[s] << " ec " << at << endl ; lnk->r->l = lnk->l ; lnk->l->r = lnk->r ; ing[s] = 1 ; unsure[s] = 0 ; for (auto b : e[s]) { cec[b]-- ; if (unsure[b]) { // if (verbose) cout << "Excluding " << w[b] << endl ; unsure[b] = 0 ; outg[b] = 1 ; link *lnk = &nodes[b] ; lnk->r->l = lnk->l ; lnk->l->r = lnk->r ; outg[b] = 1 ; unsure[b] = 0 ; for (auto c : e[b]) { if (unsure[c]) { cec[c]-- ; // if (verbose) cout << "Decreasing " << w[c] << " to " << cec[c] << endl ; link *lnk = &nodes[c] ; lnk->r->l = lnk->l ; lnk->l->r = lnk->r ; lnk->r = heads[cec[c]].r ; lnk->l = &heads[cec[c]] ; heads[cec[c]].r->l = lnk ; heads[cec[c]].r = lnk ; } } } } } if (trial == 0) { r = toting ; zerov = toting ; vector nw ; for (int i=0; i