SPOJ 7258 Lexicographical Substring Search(后缀自动机)
生活随笔
收集整理的這篇文章主要介紹了
SPOJ 7258 Lexicographical Substring Search(后缀自动机)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:http://www.spoj.com/problems/SUBLEX/
題意:給定一個字符串,每次詢問第K小的串。
思路:建立自動機。cnt[p]=sigama(cnt[son[p][i]])+1。
const int KIND=26; char s[N]; int pre[N],Lth[N],son[N][KIND+1]; i64 cnt[N]; int e,n,last;void insert() {clr(son,-1); e=0;pre[e]=-1; Lth[e]=0; last=e++;int i,r,p,q,u,x;FOR0(i,n){x=s[i]-'a';u=last; pre[e]=-1; Lth[e]=i+1; last=p=e++;for(;u!=-1&&son[u][x]==-1;u=pre[u]) son[u][x]=p;if(u==-1) pre[p]=0;else{q=son[u][x];if(Lth[q]==Lth[u]+1) pre[p]=q;else{pre[e]=pre[q]; Lth[e]=Lth[u]+1;memcpy(son[e],son[q],sizeof(son[e]));r=e++;pre[p]=pre[q]=r;for(;u!=-1&&son[u][x]==q;u=pre[u]) son[u][x]=r;}}} }int d[N],Q[N]; char transChar[N];void init() {int i,j,k,p;FOR0(i,n+1) d[i]=0;FOR0(i,e) d[Lth[i]]++;FOR1(i,n) d[i]+=d[i-1];FOR0(i,e) Q[--d[Lth[i]]]=i;FORL0(i,e-1){p=Q[i]; cnt[p]=1; k=0;FOR0(j,KIND) if(son[p][j]!=-1){cnt[p]+=cnt[son[p][j]];son[p][k++]=son[p][j];transChar[son[p][j]]=j+'a';}son[p][k]=-1;} }int main() {RD(s); n=strlen(s); insert(); init();int Q,len,i,p,q;i64 K;RD(Q);while(Q--){RD(K); p=0; len=0;while(K){i=0;K--;while(son[p][i]!=-1){q=son[p][i];if(K>=cnt[q]) K-=cnt[q];else{s[len++]=transChar[q];p=q;break;}i++;}}s[len]=0;puts(s);} }
總結
以上是生活随笔為你收集整理的SPOJ 7258 Lexicographical Substring Search(后缀自动机)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Unity与Android权限设置
- 下一篇: 老狼RAT(远程辅助管理员软件)学习笔记