HACKING
阿新 • • 發佈:2018-12-18
解題思路:
建個字尾自動機,然後在樹上跑前K個字元的dfs,直到遇到樹上沒有的即停止.
演算法複雜度O(n*m)
#include<bits/stdc++.h> #define inf 0x3f3f3f3f using namespace std; const int mx = 2e4+10; int n,m,K,cnt; char str[mx],ans[mx]; struct sam{ int ch[mx][26]; int f[mx]; int len[mx]; int c[mx]; int id[mx]; int sz,rt,last; int newnode(int v){ len[++sz] = v; memset(ch[sz],0,sizeof(ch[sz])); return sz; } void init(){ sz = 0; rt = last = newnode(0); } void insert(int c){ int p = last,np = newnode(len[last]+1); while(p&&!ch[p][c]) ch[p][c] = np,p = f[p]; if(!p) f[np] = rt; else{ int q = ch[p][c]; if(len[q]==len[p]+1) f[np] = q; else{ int nq = newnode(len[p]+1); memcpy(ch[nq],ch[q],sizeof(ch[q])); f[nq] = f[q]; f[q] = f[np] = nq; while(p&&ch[p][c]==q) ch[p][c] = nq,p = f[p]; } } last = np; } bool dfs(int p){ if(cnt==m) return 0; for(int i=K;~i;i--){ if(!ch[p][i]){ ans[cnt++] = i+'a'; return 1; } ans[cnt++] = i+'a'; if(dfs(ch[p][i])) return 1; cnt--; } return 0; } }word; int main(){ int t; scanf("%d", &t); while(t--){ scanf("%d%d%d",&n,&m,&K); K--,cnt = 0; scanf("%s",str); word.init(); for(int i=0;i<n;i++) word.insert(str[i]-'a'); word.dfs(word.rt);ans[cnt] = 0; puts(ans); } return 0; }