public void Solve() { var n = sc.Integer(); var s = sc.Scan(); var SA = new SuffixArray(s); SA.Init(); SA.BuildLCP(); var a = Enumerate(s.Length, x => x); Array.Sort(a, (l, r) => { //Debug.WriteLine("{0} {1}", l, r); if (l == r) { return(0); } var lcp = SA.GetLCP(l, r); if (Math.Max(l, r) + lcp < s.Length) { return(SA.Rank(l).CompareTo(SA.Rank(r))); } else { var lcp2 = SA.GetLCP(Math.Min(l, r), Math.Min(l, r) + lcp); if (lcp2 < Math.Max(r, l) - Math.Min(r, l)) { if (l < r) { return(SA.Rank(l + lcp).CompareTo(SA.Rank(l))); } else { return(SA.Rank(r).CompareTo(SA.Rank(r + lcp))); } } else { return(0); } } }); foreach (var x in a) { IO.Printer.Out.WriteLine(x + 1); } }
public void Solve() { var n = sc.Integer(); var k = sc.Integer(); var back = new int[k + 1]; for (int i = 0; i < k; i++) { back[i] = -1; } back[k] = n; var s = sc.Scan(n); for (int i = n - 1; i >= 0; i--) { for (int j = 0; j <= k; j++) { if (back[j] != -1 && j - s[i].Length >= 0) { back[j - s[i].Length] = Math.Max(back[j - s[i].Length], i); } } } SuffixArray sa; { var sb = new StringBuilder(); for (int i = 0; i < n; i++) { sb.Append(s[i]); sb.Append((char)('z' + 1)); } sa = new SuffixArray(sb.ToString()); sa.Init(); sa.BuildLCP(); } var dp = new bool[k + 1]; dp[0] = true; var best = Enumerate(k, x => '|'); var sum = 0; for (int i = 0; i < n; i++) { var len = s[i].Length; var zs = StringEx.ZAlgorithm(string.Concat(s[i], "$", new string(best))); var npos = -1; var npos2 = -1; var next = Enumerate(k + 1, x => - 100); for (int j = k - 1; j >= 0; j--) { if (j + len > k) { continue; } if (!dp[j]) { continue; } if (back[j + len] <= i) { continue; } var lcp = zs[len + 1 + j]; if (j + lcp != k && lcp != s[i].Length && best[j + lcp] > s[i][lcp]) { npos = j; npos2 = j + lcp; next[j + len] = npos; continue; } if (j + lcp != k && lcp != s[i].Length && best[j + lcp] < s[i][lcp]) { continue; } if (j + lcp == k || lcp == s[i].Length) { continue; } if (npos != -1) { if (j + len <= npos) { npos = j; npos2 = j + 1; next[j + len] = npos; } else { var lcp2 = sa.GetLCP(sum, sum + npos - j); if (npos - j + lcp2 == len) { next[j + len] = npos; } else if (s[i][lcp2] > s[i][npos - j + lcp2]) { npos = j; npos2 = j + lcp2; next[j + len] = npos; } } } } if (npos != -1) { for (int j = 0; j < len; j++) { best[npos + j] = s[i][j]; } for (int j = npos + len; j < k; j++) { best[j] = '|'; } for (int j = npos2 + 1; j <= k; j++) { dp[j] = false; } dp[npos] = true; dp[npos + len] = true; for (int j = 0; j <= k; j++) { if (next[j] == npos) { dp[j] |= true; } } } sum += len + 1; } IO.Printer.Out.WriteLine(best); }