public static long number_of_different_substrings(char[] s) { SuffixAutomaton sa = SuffixAutomaton.Build(s); if (!sa.sortedTopologically) { sa.SortTopologically(); } long[] D = new long[sa.gen]; for (int i = sa.gen - 1; i >= 0; i--) { D[i] = 1; for (int j = 0; j < sa.nodes[i].np; j++) { D[i] += D[sa.nodes[i].next[j].id]; } } return(D[0] - 1); }
public static char[] least_cyclic_shift(char[] s) { char[] ss = new char[s.Length * 2]; Buffer.BlockCopy(s, 0, ss, 0, sizeof(char) * s.Length); Buffer.BlockCopy(s, 0, ss, sizeof(char) * s.Length, sizeof(char) * s.Length); SuffixAutomaton sa = SuffixAutomaton.Build(ss); if (!sa.lexsorted) { sa.LexSort(); } SuffixAutomaton.Node v = sa.t0; char[] a = new char[s.Length]; int ix = 0; while (ix < s.Length) { v = v.next[0]; a[ix++] = v.key; } return(a); }