structLFDS {int to, next; }; LFDS iLink[MAXN * MAXN]; int iHead[MAXM]= {0}, isize = 0; voidInsert(int u, int v){ iLink[++ isize].to = v; iLink[isize].next = iHead[u];
iHead[u] = isize; }
int N; char str[MAXM]; vector<int> sve[MAXN];
int tr[MAXM][2]= {0}, m = 0; voidinsert(int ind){ int p = 0, n = strlen (str + 1); for (int i = 1; i <= n; i ++) { int c = str[i] - 'a'; sve[ind].push_back(c); if (! tr[p][c]) tr[p][c] = ++ m; p = tr[p][c]; } Insert (p, ind); } int fail[MAXM]= {0}; queue<int> que; int lastp[MAXM]= {0}; bitset<MAXN> g[MAXN]; voidbuild(){ for (int i = 0; i < 2; i ++) if (tr[0][i]) que.push(tr[0][i]); while (! que.empty()) { int u = que.front(); que.pop(); lastp[u] = iHead[fail[u]] ? fail[u] : lastp[fail[u]]; for (int i = 0; i < 2; i ++) { if (tr[u][i]) { fail[tr[u][i]] = tr[fail[u]][i]; que.push(tr[u][i]); } else tr[u][i] = tr[fail[u]][i]; } } } voidwork(int ind){ int p = 0; for (int i = 0; i < (int) sve[ind].size(); i ++) { int c = sve[ind][i]; p = tr[p][c]; int tp = p; for (int j = 1; j <= 2; j ++) { for (int k = iHead[tp]; k; k = iLink[k].next) { int v = iLink[k].to; if (v == ind) continue; g[v][ind] = 1; } tp = lastp[tp]; } } }
structLFS {int to, cap, next; } ; LFS Link[MAXL << 1]; int Head[MAXN << 1]= {0}, size = 1; voidInsert(int u, int v, int cap){ Link[++ size].to = v; Link[size].cap = cap; Link[size].next = Head[u];
Head[u] = size; } voidadd(int x, int y, int cap){ Insert (x, y, cap); Insert (y, x, 0); }
int S, T, _N; int depth[MAXN << 1]= {0}; boolBFS(){ while (! que.empty()) que.pop(); memset (depth, 0, sizeof (depth)); depth[S] = 1, que.push(S); while (! que.empty()) { int u = que.front(); que.pop(); for (int i = Head[u]; i; i = Link[i].next) { int v = Link[i].to, cap = Link[i].cap; if (depth[v] || ! cap) continue; depth[v] = depth[u] + 1; if (v == T) returntrue; que.push(v); } } returnfalse; } int cur[MAXN << 1]= {0}; intDinic(int p, int flow){ if (p == T) return flow; int rest = flow; for (int &i = cur[p]; i && rest; i = Link[i].next) { int v = Link[i].to, cap = Link[i].cap; if (depth[v] != depth[p] + 1 || ! cap) continue; int k = Dinic (v, min (cap, rest)); if (! k) depth[v] = - 1; Link[i].cap -= k, Link[i ^ 1].cap += k; rest -= k; } return flow - rest; } intMAXFLOW(){ int ret = 0; while (BFS ()) { for (int i = 1; i <= _N; i ++) cur[i] = Head[i]; ret += Dinic (S, INF); } return ret; } int match[MAXN]= {0};
bool tagl[MAXN]= {false}, tagr[MAXN]= {false}; voidDFS(int u){ tagr[u - N] = true; for (int i = 1; i <= N; i ++) if (g[i][u - N] && ! tagl[i]) { tagl[i] = true; DFS (match[i]); } }
intmain(){ scanf ("%d", & N); for (int i = 1; i <= N; i ++) { scanf ("%s", str + 1); insert (i); } build (); for (int i = 1; i <= N; i ++) work (i); for (int k = 1; k <= N; k ++) for (int i = 1; i <= N; i ++) if (g[i][k]) g[i] |= g[k]; S = 2 * N + 1, _N = T = 2 * N + 2; for (int i = 1; i <= N; i ++) add (S, i, 1), add (i + N, T, 1); for (int i = 1; i <= N; i ++) for (int j = 1; j <= N; j ++) if (g[i][j]) add (i, j + N, 1); int ans = N - MAXFLOW (); printf ("%d\n", ans); for (int i = 1; i <= N; i ++) if (! Link[4 * i - 2].cap) for (int j = Head[i]; j; j = Link[j].next) if (! Link[j].cap) { match[i] = Link[j].to; break; } for (int i = 1; i <= N; i ++) if (Link[4 * i].cap) DFS (i + N); for (int i = 1; i <= N; i ++) if (! tagl[i] && tagr[i]) printf ("%d ", i); puts ("");
int N, K; int P[MAXN], Q[MAXN]; int IP[MAXN], IQ[MAXN]; int T[MAXN], IT[MAXN]; int Tk[MAXN], ITk[MAXN];
voidmul(int* ret, int* p, int* q){ for (int i = 1; i <= N; i ++) ret[i] = p[q[i]]; } voidinv(int* I, int* p){ for (int i = 1; i <= N; i ++) I[p[i]] = i; } int A[MAXN], ret[MAXN]; voidpower(int* x, int p){ for (int i = 1; i <= N; i ++) ret[i] = i; while (p) { if (p & 1) { mul (A, ret, x); for (int i = 1; i <= N; i ++) ret[i] = A[i]; } mul (A, x, x); for (int i = 1; i <= N; i ++) x[i] = A[i]; p >>= 1; } for (int i = 1; i <= N; i ++) x[i] = ret[i]; } voidprint(int* a){ for (int i = 1; i <= N; i ++) { if (i > 1) putchar (' '); printf ("%d", a[i]); } puts (""); } int a[7][MAXN]; voidsolve(int n){ if (n == 0) n = 6; mul (a[1], P, ITk), mul (A, Tk, a[1]); for (int i = 1; i <= N; i ++) a[1][i] = A[i]; if (n == 1) { print (a[1]); return ; } mul (a[2], Q, ITk), mul (A, Tk, a[2]); for (int i = 1; i <= N; i ++) a[2][i] = A[i]; if (n == 2) { print (a[2]); return ; } for (int i = 1; i <= n - 2; i ++) for (int j = 1; j <= N; j ++) a[i + 2][a[i][j]] = a[i + 1][j]; print (a[n]); }
inlineintgetnum(){ int num = 0; char ch = getchar (); while (! isdigit (ch)) ch = getchar (); while (isdigit (ch)) num = (num << 3) + (num << 1) + ch - '0', ch = getchar (); return num; }
intmain(){ N = getnum (), K = getnum (); for (int i = 1; i <= N; i ++) P[i] = getnum (); for (int i = 1; i <= N; i ++) Q[i] = getnum (); inv (IP, P), inv (IQ, Q); mul (T, IQ, P), mul (A, IP, T); for (int i = 1; i <= N; i ++) T[i] = A[i]; mul (A, Q, T); for (int i = 1; i <= N; i ++) T[i] = A[i]; inv (IT, T); int k = K / 6; if (! (K % 6)) k --; for (int i = 1; i <= N; i ++) Tk[i] = T[i]; power (Tk, k); for (int i = 1; i <= N; i ++) ITk[i] = IT[i]; power (ITk, k); int r = K % 6; solve (r);