后缀数组poj2774(hdu1403)ural1517
2014-07-01 10:53
260 查看
思路:把两个串拼接起来然后求一边后缀数组和height数组,就可以了
ural1517要求把重复的串打出来,只要记录下位置就可以了。
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<queue> #include<stack> #include<map> #include<string> #include<algorithm> using namespace std; const int maxn=100010; int sa[maxn*2],Rank[maxn*2],height[maxn*2],t[maxn*2],t2[maxn*2],c[maxn*2]; int n,len; char a[maxn*2]; void build_sa(int m) { int *x=t,*y=t2; for(int i=0;i<m;i++)c[i]=0; for(int i=0;i<n;i++)c[x[i]=a[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); p=1;x[sa[0]]=0; for(int i=1;i<n;i++) x[sa[i]]=(y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k])?p-1:p++; if(p>=n)break; m=p; } } 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(a[i+k]==a[j+k])k++; height[Rank[i]]=k; } } void solve() { int ans=0; for(int i=1;i<n;i++) { if((sa[i]>len)!=(sa[i-1]>len)) ans=max(ans,height[i]); } printf("%d\n",ans); } int main() { while(scanf("%s",a)!=EOF) { len=strlen(a); a[len]='$'; scanf("%s",a+len+1); n=strlen(a); build_sa(123); getheight(); solve(); } return 0; }
ural1517要求把重复的串打出来,只要记录下位置就可以了。
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<queue> #include<stack> #include<map> #include<string> #include<algorithm> using namespace std; const int maxn=100010; int sa[maxn*2],Rank[maxn*2],height[maxn*2],t[maxn*2],t2[maxn*2],c[maxn*2]; int n,len; char a[maxn*2]; void build_sa(int m) { int *x=t,*y=t2; for(int i=0;i<m;i++)c[i]=0; for(int i=0;i<n;i++)c[x[i]=a[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); p=1;x[sa[0]]=0; for(int i=1;i<n;i++) x[sa[i]]=(y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k])?p-1:p++; if(p>=n)break; m=p; } } 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(a[i+k]==a[j+k])k++; height[Rank[i]]=k; } } void solve() { int ans=0,st=0; for(int i=1;i<n;i++) { if((sa[i]>len)!=(sa[i-1]>len)) { if(height[i]>ans) ans=height[i],st=sa[i]; } } for(int i=st;i<st+ans;i++) printf("%c",a[i]); printf("\n"); } int main() { //freopen("in.txt","r",stdin); scanf("%d",&len); scanf("%s",a); a[len]='$'; scanf("%s",a+len+1); n=2*len+1; build_sa(123); getheight(); solve(); return 0; }
相关文章推荐
- URAL 1517 Freedom of Choice
- 【POJ2774&Ural1517】Long Long Message(后缀数组)
- URAL 1517 后缀数据+最长公共前缀LCP
- Freedom of Choice URAL - 1517
- URAL 1517 Freedom of Choice (后缀数组 输出两个串最长公共子串)
- URAL 1517 Freedom of Choice
- URAL 1517 Freedom of Choice 后缀数组 入门
- [URAL-1517][求两个字符串的最长公共子串]
- Ural 1517 最长公共子序列
- URAL1517-Freedom of Choice
- [URAL1517 Freedom of Choice]
- URAL 1517 Freedom of Choice 后缀数组
- URAL 1517 Freedom of Choice
- POJ 2774 & URAL 1517(最长公共子串)
- Ural1517 Freedom of choice, 后缀数组,最长公共子串
- ural1517之最长公共子串
- URAL 1517 Freedom of Choice
- ural 1517
- URAL 2073 Log Files (模拟)
- ural 2065 - Different Sums