//求一个串最多由哪个串复制若干次得到 poj 2406
来源:互联网 发布:如何下载spss20软件 编辑:程序博客网 时间:2024/06/06 15:03
用kmp会很方便。
后缀数组的话枚举字符串(0,i),如果能够被n整除并且lcp(0,i+1)==n-i-1,那么答案就是n/(i+1);
//求一个串最多由哪个串复制若干次得到#include <iostream>#include <string>#include <cmath>#include <map>using namespace std;const int N=5000005;int wa[N],wb[N],wv[N],wsum[N];int height[N],sa[N],rank[N];int n;char str[N];int f[N];bool vis[N];int r[N];int ans;#define F(x) ((x)/3+((x)%3==1?0:tb))#define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)int c0(int *r,int a,int b){return r[a]==r[b]&&r[a+1]==r[b+1]&&r[a+2]==r[b+2];}int c12(int k,int *r,int a,int b){if(k==2)return r[a]<r[b]||r[a]==r[b]&&c12(1,r,a+1,b+1);elsereturn r[a]<r[b]||r[a]==r[b]&&wv[a+1]<wv[b+1];}void sort(int *r,int *a,int *b,int n,int m){ int i; for(i=0;i<n;i++) wv[i]=r[a[i]]; for(i=0;i<m;i++) wsum[i]=0; for(i=0;i<n;i++) wsum[wv[i]]++; for(i=1;i<m;i++) wsum[i]+=wsum[i-1]; for(i=n-1;i>=0;i--) b[--wsum[wv[i]]]=a[i]; return;}void dc3(int *r,int *sa,int n,int m){ int i,j,*rn=r+n,*san=sa+n,ta=0,tb=(n+1)/3,tbc=0,p; r[n]=r[n+1]=0; for(i=0;i<n;i++) if(i%3!=0) wa[tbc++]=i; sort(r+2,wa,wb,tbc,m); sort(r+1,wb,wa,tbc,m); sort(r,wa,wb,tbc,m); for(p=1,rn[F(wb[0])]=0,i=1;i<tbc;i++) rn[F(wb[i])]=c0(r,wb[i-1],wb[i])?p-1:p++; if(p<tbc) dc3(rn,san,tbc,p); else for(i=0;i<tbc;i++) san[rn[i]]=i; for(i=0;i<tbc;i++) if(san[i]<tb) wb[ta++]=san[i]*3; if(n%3==1) wb[ta++]=n-1; sort(r,wb,wa,ta,m); for(i=0;i<tbc;i++) wv[wb[i]=G(san[i])]=i; for(i=0,j=0,p=0;i<ta && j<tbc;p++) sa[p]=c12(wb[j]%3,r,wa[i],wb[j])?wa[i++]:wb[j++]; for(;i<ta;p++) sa[p]=wa[i++]; for(;j<tbc;p++) sa[p]=wb[j++]; return;}void calheight(int *r,int *sa,int n){int i,j,k=0;for(i=0;i<=n;i++)rank[sa[i]]=i;for(i=0;i<n;height[rank[i++]]=k)for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);}int mmin(int x,int y){return x<y?x:y;}/*void rmqinit(int n){int i,j,m,k;m=floor(log(1.0*n)/log(2.0));for(i=1;i<=n;i++)f[i][0]=height[i];for(i=1;i<=m;i++)for(j=n;j>=1;j--){f[j][i]=f[j][i-1];k=1<<(i-1);if(j+k<=n)f[j][i]=mmin(f[j][i],f[j+k][i-1]);}}*/void rmqinit2(int n){int i,s=n-sa[rank[0]];for(i=rank[0];i>=1;i--){f[i]=s;s=mmin(s,height[i]);}s=N;for(i=rank[0]+1;i<=n;i++){s=mmin(s,height[i]);f[i]=s;}}/*int get_rmq(int x,int y){int m,t;x=rank[x];y=rank[y];if(x>y) t=x,x=y,y=t; x++; m=floor(log(1.0*(y-x+1))/log(2.0)); return mmin(f[x][m],f[y-(1<<m)+1][m]); }*/int main(){int T,i,j,k,ca=0,s,t;scanf("%d",&T);while(~scanf("%s",str)){if(str[0]=='.')break;n=strlen(str);for(i=0;i<n;i++) r[i]=(int)str[i]; r[n]=0;dc3(r,sa,n+1,127);calheight(r,sa,n);rmqinit2(n);//for(i=1;i<=n;i++)//cout<<i<<' '<<f[i]<<endl;for(i=0;i<n;i++)if(n%(i+1)==0){s=f[rank[i+1]];if(s==n-i-1){ans=n/(i+1);break;}}printf("%d\n",ans);}return 0;}
- //求一个串最多由哪个串复制若干次得到 poj 2406
- POJ 3693 求重复次数最多的子串
- 求一个字符串连续出现次数最多的子串
- 求一个字符串中出现次数最多的子串
- leetcode_459. Repeated Substring Pattern 重复子串模式,判断某个字符串能否由某个字串重复若干次组成
- poj 3882 后缀数组 求一个串至少出现k次的最长重复子串的长度
- POJ 1026 位置转移构成若干环,利用环可以很快得到移位k次的字符串。
- (Relax ST1.12)POJ 2606 Rabbit hunt(给出若干个点,求最多能有多少个点共线)
- poj 1743 后缀数组+二分答案 求一个串的最长无重叠的重复出现次数最多的子串
- [腾讯笔试]求一个字符串删除若干字符可构成一个回文串
- 有一个文件ip.txt,每行一条ip记录,共若干行,下面哪个命令可以实现“统计出现次数最多的前3个ip及其次数”?
- poj 3693 求出现次数最多的连续重复子串(具体的串)黑盒
- POJ 3693 Maximum repetition substring (求重复次数最多的连续子串,4级)
- Maximum repetition substring+POj+后缀数组之求重复次数最多的连续重复子串
- POJ - 3693 Maximum repetition substring(后缀数组求重复次数最多的连续重复子串)
- POJ 3693 Maximum repetition substring (后缀数组+RMQ 求重复最多的连续子串)
- POJ-3693--后缀数组求字典序最小重复次数最多子串
- POJ 3693 Maximum repetition substring (后缀数组+RMQ 求重复最多的连续子串)
- B-样条曲线教程(B-spline Curves Notes)目录
- CAS实现的单点登录系统
- 重新开始PHP之路
- C# listBox1 总结
- 第五周任务(-)
- //求一个串最多由哪个串复制若干次得到 poj 2406
- 引用计数的应用场景举例
- 中文网页自动分类新算法
- 第五周任务(3)
- c语言实现一个单元测试框架(Unit Test Framework)
- 数据结构的C实现_二叉树的非递归遍历和层序遍历
- 第五周任务(2)
- 《TCP/IP详解》笔记----第二章 链路层
- 1-2-5组合问题的最高效完整算法