Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- char str[MX];
- int sa[MX], rk[MX], buckets[MX], lcp[MX], gl2[MX]; //using buckets for readability
- int tmp[MX], pos[MX], st[MX * 2][18], n;
- ll k, tot = 0;
- void comp_SA(){
- int mx = 260;
- for(int i = 1; i<=n; i++){
- sa[i] = i;
- rk[i] = str[i];
- }
- for(int i = 1; i >> 1 < n; i <<= 1){
- int k = i >> 1, p = k;
- for(int j = 1; j<=k; j++) buckets[j] = n - (j - 1);
- for(int j = 1; j<=n; j++) if(sa[j] > k) buckets[++p] = sa[j] - k;
- for(int j = 1; j<=n; j++) pos[j] = 0;
- for(int j = 1; j<=n; j++) pos[rk[j]]++;
- for(int j = 1; j<=mx; j++) pos[j] += pos[j - 1];
- for(int j = n; j; j--) sa[pos[rk[buckets[j]]]--] = buckets[j];
- for(int j = 1; j<=n; j++) tmp[sa[j]] = tmp[sa[j - 1]] + (rk[sa[j]] != rk[sa[j - 1]] || rk[sa[j] + k] != rk[sa[j - 1] + k]);
- for(int j = 1; j<=n; j++) rk[j] = tmp[j];
- mx = rk[sa[n]];
- if(mx == n) break;
- }
- }
- void make_lcp(){
- for(int i = 1; i<=n; i++){
- if(rk[i] == 1) cont;
- lcp[rk[i]] = max(0, lcp[rk[i - 1]] - 1);
- for(; str[i + lcp[rk[i]]] == str[sa[rk[i] - 1] + lcp[rk[i]]]; lcp[rk[i]]++);
- }
- }
- void rmq_precomp(){
- init(st, 63);
- gl2[1] = 0;
- for(int i = 2; i<=n; i++) gl2[i] = 1 + gl2[i/2];
- for(int i = 1; i<=n; i++) st[i][0] = lcp[i];
- for(int j = 1; (1 << j) <= n; j++){
- for(int i = 1; i <= n; i++){
- st[i][j] = min(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
- }
- }
- }
- int query(int a, int b){ //max prefix amoung suffix starting at a and suffix starting at b [a, b]
- //return 0;
- a++, b++;
- if(a > b) swap(a, b);
- int k = gl2[b - a];
- return min(st[a][k], st[b - (1 << k)][k]);
- }
- bool add(ll val){
- if(tot + val >= k) return 1;
- tot += val;
- return 0;
- }
- bool check(int x, int k, int pre){
- return query(k, x) >= pre;
- }
- int bsrch(int l, int r, int k, int pre){
- if(r - l < 2){
- for(int i = l; i <= r; i++){
- if(!check(i, k, pre)) return i - 1;
- }
- return r;
- }
- int mid = (l + r)/2;
- if(check(mid, k, pre)){
- return bsrch(mid, r, k, pre);
- }else{
- return bsrch(l, mid-1, k, pre);
- }
- }
- void print(int l, int r){
- for(int i = l; i<=r; i++) cout << str[i];
- cout << "\n";
- }
- int main(){
- cin.tie(0) -> sync_with_stdio(0);
- cin >> (str + 1);
- cin >> k;
- n =strlen(str + 1);
- comp_SA();
- make_lcp();
- rmq_precomp();
- int p = 0;
- for(int i = 1; i<=n; i++){
- int old = p;
- for(p = max(p, lcp[i] + 1); p <= lcp[i+1]; p++){
- int v = bsrch(i+1, n, i, p) - i+1;
- if(add(v)){
- print(sa[i], sa[i] + p - 1);
- i = n+1; break;
- }
- }
- if(i > n) break;
- p = lcp[i+1];
- int dist = (n - (sa[i] + max(old, p))) + 1;
- if(add(dist)){
- print(sa[i], sa[i] + max(old, p) + k - tot - 1);
- break;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement