SPOJ7258
來自蒟蒻XXJ的做題記錄
直接自動機寫出來
然后求一下每次trans過后還有多少字串
然后在自動機上面走就行了
#include<bits/stdc++.h> #define mem(i,j) memset(i,j,sizeof(i)) #define mcy(i,j) memcpy(i,j,sizeof(i)) using namespace std; const int MAXN=90000*2+10; int n; struct SAM{int trans[MAXN][26],fa[MAXN],lth[MAXN],siz[MAXN];int cnt,last;SAM(){cnt=0;last=++cnt;mem(trans,0);mem(fa,0);mem(lth,0);mem(siz,0);}void extend(int c){int np=++cnt,p=last;last=cnt;lth[np]=lth[p]+1;for(;p&&!trans[p][c];p=fa[p]) trans[p][c]=np;if(!p) fa[np]=1;else{int q=trans[p][c];if(lth[q]==lth[p]+1) fa[np]=q;else{int nq=++cnt;lth[nq]=lth[p]+1;mcy(trans[nq],trans[q]);fa[nq]=fa[q];fa[q]=fa[np]=nq;for(;p&&trans[p][c]==q;p=fa[p]) trans[p][c]=nq;}}}void build(char str[]){int len=strlen(str);for(int i=0;i<len;i++) extend(str[i]-'a');} }sam; char c[MAXN]; int rank[MAXN],k,t; bool cmp(int i,int j){return sam.lth[i]>sam.lth[j]; } void init(){for(int i=1;i<=sam.cnt;++i) rank[i]=i;sort(rank+1,rank+sam.cnt+1,cmp);for(int i=1;i<=sam.cnt;i++){int id=rank[i];sam.siz[id]=1;for(int j=0;j<26;j++) if(sam.trans[id][j]) sam.siz[id]+=sam.siz[sam.trans[id][j]];} } void input(){scanf("%s",c);sam.build(c);init(); } void xxj(){scanf("%d",&t);while(t--){scanf("%d",&k);int p=1;while(k){for(int i=0;i<26;i++){if(!sam.trans[p][i]) continue;if(k<=sam.siz[sam.trans[p][i]]){--k;p=sam.trans[p][i];cout<<char('a'+i);break;}else k-=sam.siz[sam.trans[p][i]];}}printf("\n");} } void hello(){freopen("a.in","r",stdin);freopen("a.ans","w",stdout); } int main(){ // hello();input();xxj();return 0; }轉載于:https://www.cnblogs.com/Xiaojianxiang/p/6599662.html
總結
- 上一篇: 朴素贝叶斯分类器简单实例
- 下一篇: 永恒之蓝