Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
尝试用SAM做了一下,比SA要慢#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int max_n=40005; int M,N; char ch[max_n]; int rec[max_n]; struct SAM{ //right就是该等价集最右边的那个endpos,sz表示该等价集endpos的大小 int fa[max_n<<1],len[max_n<<1],right[max_n<<1],sz[max_n<<1]; int son[max_n<<1][26]; int last,cnt; int counts[max_n],rk[max_n<<1]; void init(){ last=cnt=0; fa[0]=-1; len[0]=0; right[0]=0; sz[0]=1; memset(son,-1,sizeof(son)); } void add(int x){ int p=last; int np=last=++cnt; int q,nq; len[np]=right[np]=len[p]+1; sz[np]=1; while(p!=-1&&son[p][x]==-1){ son[p][x]=np; p=fa[p]; } if(p==-1){ fa[np]=0; }else{ q=son[p][x]; if(len[q]==len[p]+1){ fa[np]=q; }else{ nq=++cnt; fa[nq]=fa[q]; len[nq]=right[nq]=len[p]+1; sz[nq]=0; for(int i=0;i<26;i++) son[nq][i]=son[q][i]; fa[np]=fa[q]=nq; while(p!=-1&&son[p][x]==q){ son[p][x]=nq; p=fa[p]; } } } } void work(){ int ans1=-1,ans2=-1; for(int i=0;i<=N;i++) counts[i]=0; for(int i=0;i<=cnt;i++) counts[len[i]]++; for(int i=1;i<=N;i++) counts[i]+=counts[i-1]; for(int i=cnt;i>=0;i--) rk[--counts[len[i]]]=i; for(int i=cnt;i>0;i--){ sz[fa[rk[i]]]+=sz[rk[i]]; right[fa[rk[i]]]=max(right[fa[rk[i]]],right[rk[i]]); if(sz[rk[i]]>=M){ if((ans1<len[rk[i]])||(ans1==len[rk[i]]&&(ans2<right[rk[i]]-len[rk[i]]))){ ans1=len[rk[i]]; ans2=right[rk[i]]-len[rk[i]]; } } } if(ans1==-1){ printf("none\n"); }else{ printf("%d %d\n",ans1,ans2); } } }sam; int main(){ while(scanf("%d",&M)&&M){ scanf("%s",ch); if(M==1){ printf("%d 0\n",strlen(ch)); continue; } sam.init(); N=strlen(ch); for(int i=0;i<N;i++){ sam.add(ch[i]-'a'); } sam.work(); } return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator