Suffix

简介: Suffix

Consider n given non-empty strings denoted by s1 , s2 , · · · , sn . Now for each of them, you need to select a corresponding suffix, denoted by suf1, suf2, · · · , sufn. For each string si, the suffix sufi is a non-empty substring whose right endpoint is the endpoint of the entire string. For instance, all suffixes of the string “jiangsu” are “u”, “su”, “gsu”, “ngsu”, “angsu”, “iangsu” and itself.


All selected suffixes could assemble into a long string T = suf1+ suf2+ · · · +sufn

. Here plus signs indicate additions of strings placing the latter at the tail of the former. Your selections of suffixes would determine the lexicographical order of T . Now, your mission is to find the one with minimum lexicographical order.


Here is a hint about lexicographical order. To compare strings of different lengths, the shorter string is usually padded at the end with enough “blanks” which is a special symbol that is treated as smaller than every letters.


Input

The first line of input contains an integer T which is the total number of test cases. For each case, the first line contains an positive integer n. Each of the following n lines contains a string entirely in lowercase, corresponding to s1, s2, · · · , s n. The summation of lengths of all strings in input is smaller or equal to 500000.

Output

For each test case, output the string T with minimum lexicographical order.

题意:给你n个字符串,你必须按照输入顺序在每个字符串里取一个后缀子串,然后拼接起来,使得其字典序最小,并输出拼接后的字符串。


思路:思路:咋一看好像对每一个字符串求一次sa数组,找到排行第一的那个后缀串,然后拼接起来就ok,但是实际一想,显然不是,比如aabaa cc,如果按照上面的算法,得到aac,但是答案却是aabaac,因为后面的答案会影响前面的后缀串大小,因此我们得先求出最后的最小后缀串,然后将其加到上一个串的结尾,再求前面的串的sa数组再去找最小的后缀串,以此类推再上一个串即可。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 5;
char s[maxn], ans[maxn];
int tx[maxn];
int sa[maxn], rak[maxn];
string str[maxn];
int n, m, p, cnt;
struct node {
  int x, y, id;
}a[maxn], b[maxn];
void rsort() {
  for (int i = 1; i <= m; i++) {
    tx[i] = 0;
  }
  for (int i = 1; i <= n; i++) {
    tx[a[i].y]++;
  }
  for (int i = 1; i <= m; i++) {
    tx[i] += tx[i - 1];
  }
  for (int i = 1; i <= n; i++) {
    b[tx[a[i].y]--] = a[i];
  }
  for (int i = 1; i <= m; i++) {
    tx[i] = 0;
  }
  for (int i = 1; i <= n; i++) {
    tx[b[i].x]++;
  }
  for (int i = 1; i <= m; i++) {
    tx[i] += tx[i - 1];
  }
  for (int i = n; i >= 1; i--) {
    a[tx[b[i].x]--] = b[i];
  }
}
void ssort() {
  rsort();
  p = 0;
  for (int i = 1; i <= n; i++) {
    if (a[i].x != a[i - 1].x || a[i].y != a[i - 1].y) {
      ++p;
    }
    rak[a[i].id] = p;
  }
  for (int i = 1; i <= n; i++) {
    a[i].x = rak[i];
    a[i].id = sa[rak[i]] = i;
    a[i].y = 0;
  }
  m = p;
}
void solve(int len) {
  m = 127;
  n = min(3 * len + 27, cnt); //注意27是必须的,否则会wa掉(我也不知道为什么一定要+27
  for (int i = 1; i <= n; i++) {
    s[i] = ans[cnt - i + 1];
    a[i].x = a[i].y = s[i];
        a[i].id = i;
  }
  ssort();
  for (int j = 1; j <= n; j <<= 1) {
    for (int i = 1; i + j <= n; i++) {
      a[i].y = a[i + j].x;
    }
    ssort();
    if (p == n) {
      break;
    }
  }
}
int main() {
  int T, q;
  ios::sync_with_stdio(false);
  cin.tie(0); cout.tie(0);
  cin >> T;
  while (T--) {
    cin >> q;
    cnt = 0;
    for (int i = 1; i <= q; i++) {
      cin >> str[i];
    }
    for (int i = q; i >= 1; i--) {
      int len = str[i].size();
      for (int j = 0; j < len; j++) {
        ans[++cnt] = str[i][len - j - 1];
      }
      solve(len);
      int mm = maxn, id = 0;
      for (int j = 1; j <= len; j++) {
        if (mm > rak[j]) {
          mm = rak[j];
          id = j;
        }
      }
      cnt -= id - 1;
    }
    for (int i = cnt; i >= 1; i--) {
      cout <<(char)ans[i];
    }
    cout << endl;
  }
  return 0;
}
相关文章
|
3月前
Cannot get property 'versionCode' on extra properties extension as it does not exist
Cannot get property 'versionCode' on extra properties extension as it does not exist
128 0
jstl错误:According to TLD or attribute directive in tag file, attribute value does not accept any expr
jstl错误:According to TLD or attribute directive in tag file, attribute value does not accept any expr
MapStruct - No property named “XXX“ exists in source parameter(s). Did you mean “null“?
MapStruct - No property named “XXX“ exists in source parameter(s). Did you mean “null“?
1471 0
|
Linux C++ Windows
|
开发工具 git
error: src refspec XXX matches more than one
error: dst refspec v1.0 matches more than one. error: failed to push some refs to '' 错误原因是 branch名和tag名有相同的,在执行git push origin :branchName时,就会报上面的错 删除branch: git branch -r -d origin/branch-name //只能使用这个命令来删除branch,下面的命令不可以。
3620 0
|
Java
log4j中Pattern布局ConversionPattern详解
spring使用log4j,可以有2种方法。 1、在web.xml里不做任何配置。 log4j.properties放在classpath根目录下, 这时候生成的日志文件就没有相对路径,如果写相对路径,则会生成在安装tomcat的根路径下。 2、在web.xml设置。 &lt;context-param&gt;           &lt;param-name&gt;log4jConfi
1859 0
|
Java
According to TLD or attribute directive in tag file, attribute value does not accept any express
  在Servlet2.3及以前 jsp代码   在servlet2.4及以后 jsp代码---引入路径多了一个“jsp”
1050 0