1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 typedef long long LL; 7 8 const int MAXN = 2010; 9 10 char s[MAXN]; 11 int sa[MAXN], rank[MAXN], c[MAXN], tmp[MAXN], height[MAXN]; 12 int n, k, T; 13 14 void makesa(int n, int m) { 15 memset(c, 0, m * sizeof(int)); 16 for(int i = 0; i < n; ++i) ++c[rank[i] = s[i]]; 17 for(int i = 1; i < m; ++i) c[i] += c[i - 1]; 18 for(int i = 0; i < n; ++i) sa[--c[rank[i]]] = i; 19 for(int k = 1; k < n; k <<= 1) { 20 for(int i = 0; i < n; ++i) { 21 int j = sa[i] - k; 22 if(j < 0) j += n; 23 tmp[c[rank[j]]++] = j; 24 } 25 int j = c[0] = sa[tmp[0]] = 0; 26 for(int i = 1; i < n; ++i) { 27 if(rank[tmp[i]] != rank[tmp[i - 1]] || rank[tmp[i] + k] != rank[tmp[i - 1] + k]) 28 c[++j] = i; 29 sa[tmp[i]] = j; 30 } 31 memcpy(rank, sa, n * sizeof(int)); 32 memcpy(sa, tmp, n * sizeof(int)); 33 } 34 } 35 36 void calheight(int n) { 37 for(int i = 0, k = 0; i < n; height[rank[i++]] = k) { 38 k -= (k > 0); 39 int j = sa[rank[i] - 1]; 40 while(s[i + k] == s[j + k]) ++k; 41 } 42 } 43 44 int logn[MAXN]; 45 int best[20][MAXN]; 46 47 void init(int n = 2000) { 48 static bool done = false; 49 if(done) return ; 50 logn[0] = -1; 51 for(int i = 1; i <= n; ++i) 52 logn[i] = logn[i - 1] + ((i & (i - 1)) == 0); 53 done = true; 54 } 55 56 void initRMQ(int n) { 57 init(); 58 for(int i = 1; i <= n; ++i) best[0][i] = height[i]; 59 for(int i = 1; i <= logn[n]; ++i) { 60 int ed = n - (1 << i) + 1; 61 for(int j = 1; j <= ed; ++j) 62 best[i][j] = min(best[i - 1][j], best[i - 1][j + (1 << (i - 1))]); 63 } 64 } 65 66 int lcp(int a, int b) { 67 if(a == b) return n; 68 a = rank[a], b = rank[b]; 69 if(a > b) swap(a, b); 70 ++a; 71 int t = logn[b - a + 1]; 72 return min(best[t][a], best[t][b - (1 << t) + 1]); 73 } 74 75 int cmp(int x, int n, int y, int m) { 76 int t = lcp(x, y); 77 if(n > t && m > t) return s[x + t] - s[y + t]; 78 return n - m; 79 } 80 81 struct Node { 82 int pos, len; 83 Node() {} 84 Node(int pos, int len): pos(pos), len(len) {} 85 bool operator < (const Node &rhs) const { 86 return cmp(pos, len, rhs.pos, rhs.len) < 0; 87 } 88 void print() { 89 for(int i = pos; i < pos + len; ++i) 90 putchar(s[i]); 91 puts(""); 92 } 93 }; 94 95 const int MAXV = MAXN >> 1; 96 Node src[MAXV * MAXV]; 97 bool mat[MAXV][MAXV], ban[MAXV]; 98 int go[MAXV], cnt[MAXV]; 99 100 bool check(Node p) { 101 memset(mat, 0, sizeof(mat)); 102 memset(ban, 0, sizeof(ban)); 103 for(int i = 0; i < n; ++i) { 104 go[i] = n; 105 if(cmp(i, n, p.pos, p.len) >= 0) go[i] = min(go[i], min(p.len, lcp(p.pos % n, i))); 106 cnt[i] = go[i]; 107 for(int j = i + 1; j <= i + go[i]; ++j) 108 mat[j % n][i] = true; 109 } 110 for(int _ = 0; _ < n; ++_) { 111 bool flag = false; 112 for(int i = 0; i < n; ++i) if(!ban[i] && !cnt[i]) { 113 ban[i] = flag = true; 114 for(int j = 0; j < n; ++j) cnt[j] -= mat[i][j]; 115 } 116 if(!flag) break; 117 } 118 int c = 0; 119 for(int i = 0; i < n; ++i) if(cnt[i]) cnt[c++] = cnt[i]; 120 for(int st = 0; st < c; ++st) { 121 int x = st, y = 0; 122 while(x < st + c) x += cnt[x % c], ++y; 123 if(c >= k && y <= k) return true; 124 } 125 return false; 126 } 127 128 void solve() { 129 int c = 0; 130 for(int i = 0; i < n; ++i) 131 for(int j = 1; j <= n; ++j) src[c++] = Node(i, j); 132 sort(src, src + c); 133 //c = unique(src, src + c) - src; 134 int l = 0, r = c; 135 while(l < r) { 136 int mid = (l + r) >> 1; 137 //src[mid].print(); 138 if(!check(src[mid])) l = mid + 1; 139 else r = mid; 140 } 141 src[l].print(); 142 } 143 144 int main() { 145 scanf("%d", &T); 146 while(T--) { 147 scanf("%d%d", &n, &k); 148 scanf("%s", s); 149 memcpy(s + n, s, n * sizeof(char)); 150 s[n << 1] = 0; 151 makesa(2 * n + 1, 128); 152 calheight(2 * n); 153 initRMQ(2 * n); 154 solve(); 155 } 156 }