poj3261(后缀数组)
题意:给出一串长度为n的字符,再给出一个k值,要你求重复次数大于等于k次的最长子串长度........
思路:其实也非常简单,直接求出height值,然后将它分组,二分答案......结果就出来了.......
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define maxx 110000 int wa[maxx],wb[maxx],wsf[maxx],wv[maxx]; int sa[maxx],rank[maxx],s[maxx],height[maxx]; struct node { int num,x; }str[maxx]; int cmp1(const node a,const node b) { if(a.x<b.x) return 1; else return 0; } int cmp(int *r,int a,int b,int k) { return r[a]==r[b]&&r[a+k]==r[b+k]; } void getsa(int *r,int *sa,int n,int m) { int i,j,p,*x=wa,*y=wb,*t; for(i=0;i<m;i++) wsf[i]=0; for(i=0;i<n;i++) wsf[x[i]=r[i]]++; for(i=1;i<m;i++) wsf[i]+=wsf[i-1]; for(i=n-1;i>=0;i--) sa[--wsf[x[i]]]=i; j=1; p=1; for(;p<n;j*=2,m=p) { for(p=0,i=n-j;i<n;i++) y[p++]=i; for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; for(i=0;i<n;i++) wv[i]=x[y[i]]; for(i=0;i<m;i++) wsf[i]=0; for(i=0;i<n;i++) wsf[wv[i]]++; for(i=1;i<m;i++) wsf[i]+=wsf[i-1]; for(i=n-1;i>=0;i--) sa[--wsf[wv[i]]]=y[i]; t=x; x=y; y=t; x[sa[0]]=0; for(p=1,i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; } } void getheight(int *r,int *sa,int n) { int i,j,k=0; for(i=1;i<=n;i++) rank[sa[i]]=i; for(i=0;i<n;i++) { if(k) k--; else k=0; j=sa[rank[i]-1]; while(r[i+k]==r[j+k]) k++; height[rank[i]]=k; } } int deal(int n,int mid,int k) { int flag=1; //要注意,初始值是1.....应该一个height值,是两个字符的lcp,i与i-1的....所以初始值应该从1开始.... for(int i=2;i<=n;i++) { if(height[i]>=mid) { flag++; if(flag>=k) return 1; } else flag=1; } return 0; } int main() { int n,k; while(scanf("%d%d",&n,&k)>0) { int zd=0; for(int i=0;i<n;i++) { scanf("%d",&str[i].x); str[i].num=i; } sort(str,str+n,cmp1); int j=1; s[str[0].num]=j; for(int i=1;i<n;i++) { if(str[i].x==str[i-1].x) s[str[i].num]=j; else { j++; s[str[i].num]=j; } } s[n]=0; //for(int i=0;i<n;i++) //printf("%d ",s[i]); getsa(s,sa,n+1,j+10); getheight(s,sa,n); int left=0,right=n,count=0,mid; while(left<=right) { mid=(left+right)/2; if(deal(n,mid,k)) { if(count<mid) count=mid; //printf("%d\n",mid); left=mid+1; } else right=mid-1; } printf("%d\n",count); } return 0; }
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。