Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ///#include <stdio.h>
- ///#include <iostream>
- ///#include <cstring>
- ///#include <cmath>
- ///#include <algorithm>
- ///#include <string>
- ///#include <vector>
- ///#include <map>
- ///#include <set>
- ///#include <queue>
- ///#include <cstdlib>
- ///#include <limits>
- ///#include <iostream>
- ///#include <sstream>
- ///#include <unordered_set>
- ///#include <unordered_map>
- ///#include <random>
- #include <bits/stdc++.h>
- ///#include <bits/stdtr1c++.h>
- ///#include <ext/pb_ds/assoc_container.hpp>
- ///#include <ext/pb_ds/tree_policy.hpp>
- using namespace std;
- ///using namespace __gnu_pbds;
- #define MAX 500005
- #define EPS 1e-9
- #define ull unsigned long long
- #define ll long long
- #define inf INT_MAX
- #define pi acos(-1.0)
- #define vi vector<int>
- #define vl vector<long long>
- #define pii pair<int,int>
- #define pll pair<long long,long long>
- #define mp make_pair
- #define mem(a, v) memset(a, v, sizeof (a))
- #define mod 1000000007
- #define all(a) a.begin(),a.end()
- #define rall(a) a.rbegin(),a.rend()
- #define ff first
- #define ss second
- #define arsort(ar,n) sort(ar,ar+n);
- #define vsort(v) sort(v.begin(),v.end())
- #define vrev(v) reverse(v.begin(),v.end())
- #define arrev(ar,n) reverse(ar,ar+n)
- #define pb push_back
- #define popb pop_back
- #define booster() ios_base::sync_with_stdio(0); cin.tie(0);
- #define read(f) freopen(f, "r", stdin)
- #define scani(x) scanf("%d",&x)
- #define scanl(x) scanf("%I64d",&x)
- #define scand(x) scanf("%lf",&x)
- #define scans(x) scanf("%s",x)
- #define OUT(x) printf("%d\n",x)
- #define OUTS(x) printf("%d ",x)
- #define min3(a,b,c) min(a,min(b,c))
- #define max3(a,b,c) max(a,max(b,c))
- #define min4(a,b,c,d) min(min(a,b),min(c,d))
- #define max4(a,b,c,d) max(max(a,b),max(c,d))
- #define max5(a,b,c,d,e) max(max3(a,b,c),max(d,e))
- #define min5(a,b,c,d,e) min(min3(a,b,c),min(d,e))
- #define bitCheck(a,k) ((bool)(a&(1<<(k))))
- #define bitOff(a,k) (a&(~(1<<(k))))
- #define bitOn(a,k) (a|(1<<(k)))
- #define bitFlip(a,k) (a^(1<<(k)))
- #define POPCOUNT __builtin_popcount
- #define POPCOUNTLL __builtin_popcountll
- #define RIGHTMOST __builtin_ctzll
- #define LEFTMOST(x) (63-__builtin_clzll((x)))
- #define scani2(a,b) scani(a) , scani(b)
- #define scani3(a,b,c) scani(a), scani(b), scani(c)
- #define scani4(a,b,c,d) scani(a), scani(b), scani(c), scani(d)
- #define scani5(a,b,c,d,e) scani(a), scani(b), scani(c), scani(d) , scani(e)
- #define rnd mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
- /*********************Ordered Multiset*************************/
- /*** Needs C++11 or C++14 ***/
- /// Treap supporting duplicating values in set
- /// Maximum value of treap * ADD must fit in long long
- /*
- struct Treap{ /// hash = 96814
- int len;
- const int ADD = 1000010;
- const int MAXVAL = 1000000010;
- tr1::unordered_map <long long, int> mp; /// Change to int if only int in treap
- tree<long long, null_type, less<long long>, rb_tree_tag, tree_order_statistics_node_update> T;
- Treap(){
- len = 0;
- T.clear(), mp.clear();
- }
- inline void clear(){
- len = 0;
- T.clear(), mp.clear();
- }
- inline void insert(long long x){
- len++, x += MAXVAL;
- int c = mp[x]++;
- T.insert((x * ADD) + c);
- }
- inline void erase(long long x){
- x += MAXVAL;
- int c = mp[x];
- if (c){
- c--, mp[x]--, len--;
- T.erase((x * ADD) + c);
- }
- }
- /// 1-based index, returns the K'th element in the treap, -1 if none exists
- inline long long kth(int k){
- if (k < 1 || k > len) return -1;
- auto it = T.find_by_order(--k);
- return ((*it) / ADD) - MAXVAL;
- }
- /// Count of value < x in treap
- inline int count(long long x){
- x += MAXVAL;
- int c = mp[--x];
- return (T.order_of_key((x * ADD) + c));
- }
- /// Number of elements in treap
- inline int size(){
- return len;
- }
- };
- typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>ordered_set;///*X.find_by_order();X.order_of_key();
- template <class T> inline bool isLeap(T y) {return (y % 400 == 0) || (y % 100 ? y % 4 == 0 : false); }*/
- template< class T > inline T gcd(T a, T b) { return (b) == 0 ? (a) : gcd((b), ((a) % (b))); }
- template< class T > inline T lcm(T a, T b) { return ((a) / gcd((a), (b)) * (b)); }
- template <class T> inline T BigMod(T Base,T power,T M=mod){if(power==0)return 1;if(power&1)return ((Base%M)*(BigMod(Base,power-1,M)%M))%M;else{T y=BigMod(Base,power/2,M)%M;return (y*y)%M;}}
- template <class T> inline T ModInv (T A,T M = mod){return BigMod(A,M-2,M);}
- int fx[] = {-1,+0,+1,+0,+1,+1,-1,-1,+0};
- int fy[] = {+0,-1,+0,+1,+1,-1,+1,-1,+0};
- int day[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- /*********************** let the play begin() *********************************/
- /// ********** FASTER one *******************///
- namespace mf
- {
- const int MAXN = 10004;
- struct edge {
- int a, b, cap, flow ;
- edge(int _a,int _b,int _c,int _d) {
- a=_a,b=_b,cap=_c,flow=_d;
- }
- } ;
- int INF=1500000001;
- int n, s, t, d [ MAXN*2 ] , ptr [ MAXN*2 ] , q [ MAXN*2*10 ] ;
- vector < edge > e ;
- vector < int > g [ MAXN * 2 ] ;
- void addEdge ( int a, int b, int cap ,int cap2=0) {
- edge e1 =edge( a, b, cap, 0 ) ; /// forward cap
- edge e2 =edge( b, a, cap2 , 0 ) ; /// backward cap change here if needed
- g [ a ] . push_back ( ( int ) e. size ( ) ) ;
- e. push_back ( e1 ) ;
- g [ b ] . push_back ( ( int ) e. size ( ) ) ;
- e. push_back ( e2 ) ;
- }
- bool bfs ( ) {
- int qh = 0 , qt = 0 ;
- q [ qt ++ ] = s ;
- memset ( d, -1 , sizeof d ) ;
- d [ s ] = 0 ;
- while ( qh < qt && d [ t ] == - 1 ) {
- int v = q [ qh ++ ] ;
- for ( size_t i = 0 ; i < g [ v ] . size ( ) ; ++ i ) {
- int id = g [ v ] [ i ] ,
- to = e [ id ] . b ;
- if ( d [ to ] == - 1 && e [ id ] . flow < e [ id ] . cap ) {
- q [ qt ++ ] = to ;
- d [ to ] = d [ v ] + 1 ;
- }
- }
- }
- return d [ t ] != -1;
- }
- int dfs ( int v, int flow ) {
- if ( ! flow ) return 0 ;
- if ( v == t ) return flow ;
- for ( ; ptr [ v ] < ( int ) g [ v ] . size ( ) ; ++ ptr [ v ] ) {
- int id = g [ v ] [ ptr [ v ] ] ,
- to = e [ id ] . b ;
- if ( d [ to ] != d [ v ] + 1 ) continue ;
- int pushed = dfs ( to, min ( flow, e [ id ] . cap - e [ id ] . flow ) ) ;
- if ( pushed ) {
- e [ id ] . flow += pushed ;
- e [ id ^ 1 ] . flow -= pushed ;
- return pushed ;
- }
- }
- return 0 ;
- }
- ll dinic ( ) {
- ll flow = 0 ;
- for ( ;; ) {
- if ( !bfs () ) break ;
- memset ( ptr, 0 , sizeof ptr ) ;
- while ( int pushed = dfs ( s, INF ) ) {
- flow += (ll)pushed ;
- if(pushed == 0)break;
- }
- }
- return flow ;
- }
- void init(int src, int dest , int nodes){
- e.clear();
- for(int i = 0;i<=n+n;i++) g[i].clear();
- n = nodes; s = src; t = dest;
- }
- };
- int prime[MAX],p,flag[MAX];
- void sieve(int n){
- double z = sqrt(n);
- for(int i = 4;i<=n;i+=2)flag[i] = 1;
- for(int i = 3;i<=z;i+=2){
- if(!flag[i]){
- for(ll j = i*i;j<=n;j+=i+i)flag[j] = 1;
- }
- }
- prime[p++] = 2;
- for(int i = 3;i<=n;i+=2){
- if(!flag[i])prime[p++] = i;
- }
- }
- int nn,arr[MAX];vi v[MAX],ans[MAX];int vis[MAX],cnt;
- void dfs(int s){
- if(vis[s])return ;
- vis[s] = 1;
- ans[cnt].pb(s);
- for(auto it : v[s]){
- if(!vis[it])dfs(it);
- }
- }
- int main()
- {
- booster()
- ///read("input.txt");
- sieve(100000);
- cin>>nn;
- for(int i = 0;i<nn;i++){
- cin>>arr[i];
- }
- mf::init(0,nn+1,nn+3);
- for(int i = 0;i<nn;i++){
- for(int j = i+1;j<nn;j++){
- if(!flag[arr[i]+arr[j]]){
- if(arr[i]&1)mf::addEdge(i+1,j+1,1);
- else mf::addEdge(j+1,i+1,1);
- }
- }
- }
- int pnt = 0;
- for(int i = 0;i<nn;i++){
- if(arr[i]&1)mf::addEdge(0,i+1,2),pnt++;
- else mf::addEdge(i+1,nn+1,2);
- }
- int x = mf::dinic();
- ///cout<<x<<endl;
- if(x!=nn||pnt!=nn-pnt)cout<<"Impossible";
- else {
- for(int i = 0;i<nn;i++){
- int sz = mf::g[i+1].size();
- for(int j = 0;j<sz;j++){
- int indx = mf::g[i+1][j];
- if(mf::e[indx].flow==1){
- int a = mf::e[indx].a;
- int b = mf::e[indx].b;
- v[a].pb(b);
- v[b].pb(a);
- }
- }
- }
- for(int i = 1;i<=nn;i++){
- if(!vis[i]){
- cnt++;
- dfs(i);
- }
- }
- cout<<cnt<<endl;
- for(int i = 1;i<=cnt;i++){
- cout<<ans[i].size()<<" ";
- for(auto it : ans[i])cout<<it<<" ";
- cout<<endl;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement