POJ 3693(后缀数组)
来源:互联网 发布:大华图像算法工程师 编辑:程序博客网 时间:2024/06/05 03:01
(http://acm.hust.edu.cn/vjudge/contest/view.action?cid=105595#problem/H)
题意:给定字符串s,寻找其子串T,使得T循环节数最多
(len(T)/len(T的最小循环节)最大)。
解法:还是枚举循环节长度,那么T的第一个循环节一定包含0,T,2T…其中的一个。时间复杂度就是O(nlgn).
同样套路的题还有UVA 10829.都是这种枚举L,计算lcp(i,i+L)的套路。
#include <stdio.h>#include <iostream>#include <algorithm>#include <string.h>#include <vector>using namespace std;#define ll long long#define inf 1e18#define clr(x,y) memset(x,y,sizeof x)#define FOR(i,a,b) \ for(i=a;a<b?i<=b:i>=b;a<b?i++:i--)const int maxn = 100000*2+20;struct suffix_array{ char s[maxn]; int sa[maxn] , t[maxn] , t2[maxn] , c[maxn]; int n; void build_sa(int m) { int i,*x=t,*y=t2; FOR(i,0,m-1) c[i]=0; FOR(i,0,n-1) c[x[i]=s[i]]++; FOR(i,1,m-1) c[i]+=c[i-1]; FOR(i,n-1,0) sa[--c[x[i]]]=i; for(int k=1;k<=n;k<<=1) { int p=0; FOR(i,n-k,n-1) y[p++]=i; FOR(i,0,n-1) if(sa[i]>=k) y[p++]=sa[i]-k; FOR(i,0,m-1) c[i]=0; FOR(i,0,n-1) c[x[y[i]]]++; FOR(i,0,m-1) c[i]+=c[i-1]; FOR(i,n-1,0) sa[--c[x[y[i]]]]=y[i]; swap(x,y); p=1; x[sa[0]]=0; FOR(i,1,n-1) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&& y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++; m=p; } //printf("finish build\n"); } int Rank[maxn],height[maxn]; void getHeight() { int k=0; for(int i=0;i<n;i++) Rank[sa[i]]=i; for(int i=0;i<n;i++){ if(k) k--; int j=sa[Rank[i]-1]; while(s[i+k]==s[j+k]) k++; height[Rank[i]]=k; } } int d[maxn][30],flog[maxn]; void RMQ_init() { for(int i=0;i<n;i++) d[i][0]=height[i]; flog[0]=-1; for(int i=1;i<=n;i++) flog[i]=flog[i>>1]+1; for(int j=1;(1<<j)<=n;j++) for(int i=0;i+(1<<j)<=n;i++) d[i][j]=min(d[i][j-1],d[i+(1<<(j-1))][j-1]); } int RMQ(int L,int R){ int k=flog[R-L+1]; return min(d[L][k],d[R-(1<<k)+1][k]); } int lcp(int j,int k) { if(j==k) return n-k; if(Rank[j]>Rank[k]) swap(j,k); return RMQ(Rank[j]+1,Rank[k]); } void init(char *ss) { strcpy(s,ss); n = strlen(s)+1; //printf("in\n"); build_sa(255); getHeight(); RMQ_init(); }}su,su2;int d[maxn][30],flog[maxn];void RMQ_init(int *A,int n){ for(int i=0;i<n;i++) d[i][0]=A[i]; flog[0]=-1; for(int i=1;i<=n;i++) flog[i]=flog[i>>1]+1; for(int j=1;(1<<j)<=n;j++) for(int i=0;i+(1<<j)<=n;i++) d[i][j]=min(d[i][j-1],d[i+(1<<(j-1))][j-1]);}int RMQ(int L,int R){ int k=flog[R-L+1]; return min(d[L][k],d[R-(1<<k)+1][k]);}void Rev(char *s){ int l=0,r=strlen(s)-1; while(l<r) swap(s[l++],s[r--]);}char s[maxn],s2[maxn];int main(){ //freopen("input.txt","r",stdin); //freopen("output.txt","w",stdout); int CASE=0; while(~scanf("%s",s)) { if(strcmp(s,"#")==0) break; int len = strlen(s);// printf("len %d\n",len); su.init(s); strcpy(s2,s); Rev(s2); su2.init(s2); int ans=0,ansr=-1,ansl=-1; RMQ_init(su.Rank,len); for(int l=1;l<=len;l++) { for(int i=0;i+l<len;i+=l) if( s[i] == s[i+l] ) { //printf("i %d l %d\n",i,l); int lcp1 = su.lcp(i,i+l) , lcp2 = su2.lcp(len-i-1,len-i-l-1);// if(i==0&&l==1)printf("%d %d %d\n",len-i-1,len-i-l-1,su2.lcp(len-i-1,len-i-l-1)); if( lcp1+lcp2-1>=l ) { int L = lcp1 + lcp2 - 1; int r = L/l +1; int pos = su.sa[ RMQ(i - lcp2 + 1 , i-lcp2+1+L%l) ]; if( r > ansr || (r==ansr&&su.Rank[pos] < su.Rank[ans]) ) { ans = pos; ansr = r; ansl = r*l;// printf("i %d lcp1 %d lcp2 %d r %d pos %d\n",i,lcp1,lcp2,r,pos); } } } } printf("Case %d: ",++CASE); if( ansr==-1 ) { char a='z'; for(int i=0;i<len;i++) a=min(s[i],a); printf("%c\n",a); continue; } for(int i=0;i<ansl;i++) printf("%c",s[i+ans]); printf("\n"); } return 0;}
0 0
- POJ 3693(后缀数组)
- poj 3693 (后缀数组)
- poj 3693(后缀数组)
- 【后缀数组】poj 3693
- POJ 3693 后缀数组
- poj-3693(后缀数组+RMQ)
- poj 3693 后缀数组+RMQ
- POJ 3693 后缀数组+RMQ
- POJ 3693 后缀数组+RMQ
- POJ 1734(后缀数组)
- POJ 2774(后缀数组)
- POJ 3415(后缀数组)
- poj-2774(后缀数组)
- poj 3693 Maximum repetition substring(后缀数组好题)
- POJ 3693 Maximum repetition substring(RMQ+后缀数组)
- POJ 3693 Maximum repetition substring (后缀数组)
- POJ 3693 - Maximum repetition substring (后缀数组)
- POJ 3693 Maximum repetition substring(后缀数组)
- java - 常见面试题
- 腾讯云服务器数据跨地域转移复制方法腾讯云不同区域数据复制
- 镇楼
- 卸载lantern后ie无法上网问题。卸载wifi共享精灵后无法上网
- 统计学习方法概论
- POJ 3693(后缀数组)
- ZOJ 3480 Duck Typing
- Struts2 Action
- [BZOJ1073][SCOI2007]kshort
- Java拓扑图之设备机架图
- 工欲善其事必先利其器——PowerDesigner(一)简介
- spring mvc controller间跳转 重定向 传参
- Java 拓扑图之设备面板图PortDemo
- [数据重现-文件系统原理精解与数据恢复最佳实践].(马林).影印版及光盘下载地址