spoj 687. Repeats
来源:互联网 发布:淘宝联盟第三方服务商 编辑:程序博客网 时间:2024/05/10 19:11
题目链接:http://www.spoj.pl/problems/REPEATS/
题目思路:后缀数组求重复次数最多的连续重复子串,借用别人的思路写的。
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<string>#include<queue>#include<algorithm>#include<vector>#include<stack>#include<list>//#include<iostream>#include<map>using namespace std;#define inf 0x3f3f3f3f#define M 110000int max(int a,int b){return a>b?a:b;}int min(int a,int b){return a<b?a:b;}int sa[M],rank[M],height[M],r[M];int wa[M],wb[M],wv[M],ws[M],dp[20][M],mm[M];bool cmp(int *y,int a,int b,int l){ return y[a]==y[b]&&y[a+l]==y[b+l];}void da(int n,int m){ int i,j,p; int *x=wa,*y=wb; for(i=0;i<m;i++) ws[i]=0; for(i=0;i<n;i++) ws[x[i]=r[i]]++; for(i=1;i<m;i++) ws[i]+=ws[i-1]; for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i; for(j=1,p=1;p<n;j*=2,m=p) { p=0; for(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<m;i++) ws[i]=0; for(i=0;i<n;i++) wv[i]=x[y[i]]; for(i=0;i<n;i++) ws[wv[i]]++; for(i=1;i<m;i++) ws[i]+=ws[i-1]; for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i]; swap(x,y); x[sa[0]]=0; p=1; for(i=1;i<n;i++) { if(cmp(y,sa[i-1],sa[i],j)) x[sa[i]]=p-1; else x[sa[i]]=p++; } }}void calh(int n){ int i,k,tmp; for(i=1;i<=n;i++) rank[sa[i]]=i; k=0; for(i=0;i<n;i++) { tmp=sa[rank[i]-1]; for(;r[i+k]==r[tmp+k];k++) ; height[rank[i]]=k; k?--k:0; }}void init(int n){ int i,j; mm[0]=-1; for(i=1;i<=n;i++) { if((i&(i-1))==0) mm[i]=mm[i-1]+1; else mm[i]=mm[i-1]; } for(i=1;i<=n;i++) dp[0][i]=height[i]; for(i=1;i<=mm[n];i++) { int tmp=1<<(i-1); for(j=1;j+tmp<=n;j++) dp[i][j]=min(dp[i-1][j],dp[i-1][j+tmp]); }}int lcp(int a,int b){ a=rank[a],b=rank[b]; if(a>b) swap(a,b); a++; int l=mm[b-a+1]; b-=(1<<l)-1; return min(dp[l][a],dp[l][b]);}char s[10];int main(){ int i,j,t,n,num,k,ans; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=0;i<n;i++) { scanf("%s",s); r[i]=s[0]; } r[n]=0; da(n+1,128); calh(n); init(n); // for(i=1;i<=n;i++) // { // printf("i %d sa %d height %d\n",i,sa[i],height[i]); // } // puts("akkk"); ans=1; for(i=1;i<=n/2;i++) { for(j=0;j+i<n;j+=i) { k=lcp(j,j+i); num=k/i; int tmp=j-(i-k%i); if(tmp>=0&&lcp(tmp,tmp+i)>=i) num++; ans=max(ans,num); } } printf("%d\n",ans+1); }}
- spoj 687. Repeats
- SPOJ 687. Repeats(后缀数组)
- Repeats SPOJ
- SPOJ REPEATS SA
- 【后缀数组】SPOJ REPEATS
- SPOJ REPEATS(后缀数组)
- spoj 687 repeats
- SPOJ REPEATS 后缀数组
- Repeats (spoj 687)
- spoj Repeats 后缀数组
- SPOJ 687. Repeats(后缀数组求最长重复子串)
- spoj 687 Repeats//后缀数组
- SPOJ-REPEATS之后缀数组
- SPOJ 687 REPEATS Repeats 后缀数组 + RMQ预处理
- SPOJ 687 Repeats 后缀数组+暴力+rmq
- poj 3693/hdu 2459 Maximum repetition substring spoj 687. Repeats ( 后缀数组 重复次数最多的连续重复子串)
- SPOJ REPEATS - Repeats(后缀数组[重复次数最多的连续重复子串])
- SPOJ SUBST1 POJ 2406 POJ REPEATS 后缀数组小结
- play! First
- 类的构造函数、析构函数、拷贝构造函数与赋值函数
- 复杂数据类型 (代码大全 第十二章)
- 在VC/MFC中为程序定义全局快捷键
- ubuntu下adsl拨号上网
- spoj 687. Repeats
- c/c++测试题
- hdu3400 Line belt
- SSH隧道与端口转发及内网穿透
- Android开发之闪屏实现
- ExtJs ComboBox浅析
- jQuery要怎么写才能速度最快
- 有n个数,使前面m个变为后面的
- 驱动模块读写寄存器