void sol(){ if(s2<s1){ vi t=a;a=b;b=t; ll x=s1;s1=s2;s2=x; t=ida;ida=idb;idb=t; fliped=!fliped; } if(a.empty() || b.empty())return ; if(abs(s1-s2)==0){return ;} ll diff = abs(s2 - s1); ll Y = diff; int x,y; x=y=0; // printf("diff = %lld\n",diff); for (int i = 0; i < a.size(); ++i) { vi::iterator it = lower_bound(b.begin(), b.end(), diff/2 + a[i]); int j = it-b.begin(); if(j && j == b.size())j--; // printf("i,j=%d,%d\n",i,j); ll ns1 = s1 - a[i] + b[j]; ll ns2 = s2 - b[j] + a[i]; // printf("debug a[%d] = %d b[%d] = %d\n",i,a[i],j,b[j]); // printf("debug ns1 = %lld ns2 = %lld\n",ns1,ns2); if(abs(ns1 - ns2) < Y){ x = i; y = j; // printf("debug %d %d\n",x,y); Y = abs(ns1 - ns2); } } if(Y<diff){ // printf("swaping a[%d] b[%d] diff = %lld\n", x,y, Y); if(fliped) ans.push_back(ii(idb[y],ida[x])); else ans.push_back(ii(ida[x],idb[y])); s1 = s1 - a[x] + b[y]; s2 = s2 + a[x] - b[y]; } // printf("x,y = %d %d\n",x,y); a.erase(move(a,x)); ida.erase(move(ida,x)); b.erase(move(b,y)); idb.erase(move(idb,y)); }
bool query(const vvpi& T, const vi& Qin) { if ( Qin.empty() ) return true; if ( Qin.size() == 1 ) return !T[ Qin[0] ].empty(); auto Q = Qin; // copy the query sort(Q.begin(), Q.end()); for ( auto p : T[ Q[0] ] ) { int i, k; tie(i, k) = p; int s = 1; while ( k <= Q[s] && k > -1 ) { s += k == Q[s]; if ( s == Q.size() ) return true; auto it = lower_bound( T[k].begin(), T[k].end(), i, [](const pi& x, int val) -> bool { return x.first < val; } ); if (it == T[k].end() || it->first != i) break; k = it->second; } } return false; }
bool query(const vvi& T, const vi& Q) { if ( Q.empty() ) return true; vi S = T[ Q[0] ]; if ( Q.size() == 1 ) return !S.empty(); for ( int i = 1; i < Q.size(); ++i ) { const auto& TQi = T[ Q[i] ]; workspace_vec.clear(); set_intersection( S.begin(), S.end(), TQi.begin(), TQi.end(), back_inserter(workspace_vec)); S = workspace_vec; if ( S.empty() ) return false; } return !S.empty(); }
void out(vi & a) { printf("%d", a.empty() ? 0 : a.back()); for (int i = int(a.size()) - 2; i >= 0; i--) printf("%09d", a[i]); }
int main() { #ifdef DEBUG time_t startt = clock(); #endif isprime.set(); isprime[0] = isprime[1] = 0; for(int i = 0; i<20015; i++) if(isprime[i]) { for(int j = i*i; j<20015; j+= i) isprime[j] = 0; } scanf("%d", &n); p.assign(n+2, 0); q.assign(n+2, 0); int cnt[] = {0, 0}; s = n; t = n+1; memset(res, 0, sizeof res); for(int i = 0; i<n; i++) { scanf("%d", a+i); if(a[i] & 1) { cnt[0]++; res[s][i] = 2; } else { res[i][t] = 2; cnt[1]++; } } if(cnt[0] != cnt[1]) { puts("Impossible"); return 0; } for(int i = 1; i<n; i++) for(int j = 0; j<i; j++) if(isprime[a[i]+a[j]]) { if(a[i] & 1) res[i][j] = 1; else res[j][i] = 1; } int flow = 0; n += 2; while(1) { f = 0; vis.reset(); queue< int > q; p.assign(n, -1); q.push(s); vis[s] = 1; while(!q.empty()) { int u = q.front(); q.pop(); if(u == t) break; for(int i = 0; i<n; i++) if(!vis[i] && res[u][i] > 0) p[i] = u, vis[i] = 1, q.push(i); } augment(t, 1000000); if(f == 0) break; flow += f; } if(flow != (cnt[0]<<1)) { puts("Impossible"); return 0; } vis.set(); n -= 2; for(int i = 0; i<n; i++) if(vis[i] && (a[i] & 1)) { int v = i; ans.push_back(vi()); while(vis[v]) { ans.back().push_back(v); vis[v] = 0; for(int j = 0; j<n; j++) { if(vis[j] && ((a[j] & 1) == 0) && res[j][v]) { v = j; break; } } ans.back().push_back(v); vis[v] = 0; for(int j = 0; j<n; j++) if(vis[j] && (a[j] & 1) && res[v][j]) { v = j; break; } } } printf("%d\n", ans.size()); for(int i = 0; i<ans.size(); i++) { printf("%d", ans[i].size()); for(int j = 0; j< ans[i].size(); j++) printf(" %d", ans[i][j] + 1); printf("\n"); } #ifdef DEBUG cerr << "Running time : " << (double)(clock()-startt) * 1000 / CLOCKS_PER_SEC << " ms" << endl; int T = time(NULL)-1491365861; cerr << "Time : " << T/60 << " minutes " << T%60 << " secs" << endl; #endif return 0; }