poj3693后缀数组(插点)

来源:互联网 发布:淘宝高马二溪茶怎么样 编辑:程序博客网 时间:2024/05/16 09:57

确是够坑

 

#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<cstdlib>using namespace std;const int N=100005*2;int n,len;char ch[N];int s[N],sa[N],height[N],c[N],rank[N],t1[N],t2[N];int f[N][20],tmp[N],kk[N];int ans[N],mx,num;void clear(){n=mx=num=0;memset(ans,0,sizeof(ans));memset(sa,0,sizeof(sa));memset(height,0,sizeof(height));memset(rank,0,sizeof(rank));memset(f,0,sizeof(f));memset(tmp,0,sizeof(tmp));}void build_sa()  {      int m=29,*x=t1,*y=t2;      for (int i=0;i<m;i++) c[i]=0;      for (int i=0;i<n;i++) c[x[i]=s[i]]++;      for (int i=1;i<m;i++) c[i]+=c[i-1];      for (int i=n-1;i>=0;i--) sa[--c[x[i]]]=i;            for (int k=1;k<=n;k<<=1)      {          int p=0;          for (int i=n-k;i<n;i++) y[p++]=i;          for (int i=0;i<n;i++) if (sa[i]>=k) y[p++]=sa[i]-k;                    for (int i=0;i<m;i++) c[i]=0;          for (int i=0;i<n;i++) c[x[y[i]]]++;          for (int i=1;i<m;i++) c[i]+=c[i-1];          for (int i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];          swap(x,y);          x[sa[0]]=0;p=1;          for (int i=1;i<n;i++)          x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p-1:p++;          if (p>=n) break;          m=p;       }  }  void build_height()  {      int k=0;     for (int i=0;i<n;i++) rank[sa[i]]=i;      for (int i=0;i<n-1;i++)      {          if (k) k--;          int j=sa[rank[i]-1];          while (s[j+k]==s[i+k]) k++;          height[rank[i]]=k;      }  }  void build_rmq(){for (int i=0;i<n;i++) f[i][0]=height[i];for (int k=1;(1<<k)<=n;k++)for (int j=0;j<n;j++)if (j+(1<<k)-1<n)f[j][k]=min(f[j][k-1],f[j+(1<< k-1 )][k-1]);}int rmq(int x,int y){if (x>y) swap(x,y);x++;int tt=(int)(log(1.0*(y-x+1))/log(2.0));return min(f[x][tt],f[y-(1<<tt)+1][tt]); }int front(int x,int y){return rmq(rank[x],rank[y]);}int back(int x,int y){return rmq(rank[n-x-2],rank[n-y-2]);}void work(){len=strlen(ch);clear();for (int i=0;i<len;i++) s[n++]=ch[i]-'a'+1;s[n++]=27;for (int i=len-1;i>=0;i--) s[n++]=ch[i]-'a'+1;s[n++]=0;build_sa();build_height();build_rmq();for (int l=1;l<=len/2;l++){ans[l]=1;for (int i=0;i+l<len;i+=l){if (s[i]!=s[i+l]) continue;int L=front(i,i+l);if (i!=0) L+=back(i-1,i+l-1);int tt=L/l+1;if (tt>ans[l]) ans[l]=tt;}if (ans[l]>mx) {mx=ans[l];num=0;tmp[++num]=l;}else if (ans[l]==mx) tmp[++num]=l;}if (mx==1){char ttt='z';for (int i=0;i<len;i++) ttt=min(ttt,ch[i]);printf("%c\n",ttt);return ;}for (int i=1;i<n;i++)if (sa[i]<len){for (int j=1;j<=num;j++)if (sa[i]+tmp[j]<len){int tt=front(sa[i],sa[i]+tmp[j]);if (tt>=(mx-1)*tmp[j]) {for (int l=0;l<mx*tmp[j];l++) printf("%c",ch[sa[i]+l]);printf("\n");return ;}} else break;}}int main(){int tt=0;while(scanf("%s",ch)!=EOF){tt++;if (ch[0]=='#') break;printf("Case %d: ",tt);work();}return 0;}


 

0 0
原创粉丝点击