ural 1297 Palindrome(后缀数组)
来源:互联网 发布:旅游线路图软件 编辑:程序博客网 时间:2024/05/17 08:20
题意:给出一个串,求最长回文子串,若有多个,输出第一次出现的。
思路:把这个串后面加一个'$',把串翻转再复制一份到后面,然后求这个串的后缀数组,枚举最长回文串可能出现的位置,利用求lcp算最长回文串。
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<set>#include<stack>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-9#define pi acos(-1.0)using namespace std;typedef long long ll;const int maxn=3000+10;char s[maxn];int sa[maxn],t[maxn],t2[maxn],c[maxn];int rank[maxn],height[maxn];void build_sa(int n,int m){ int i,*x=t,*y=t2; for(i=0;i<m;++i) c[i]=0; for(i=0;i<n;++i) c[x[i]=s[i]]++; for(i=1;i<m;++i) c[i]+=c[i-1]; for(i=n-1;i>=0;--i) sa[--c[x[i]]]=i; for(int k=1;k<=n;k<<=1) { int p=0; for(i=n-k;i<n;++i) y[p++]=i; for(i=0;i<n;++i) if(sa[i]>=k) y[p++]=sa[i]-k; for(i=0;i<m;++i) c[i]=0; for(i=0;i<n;++i) c[x[y[i]]]++; for(i=1;i<m;++i) c[i]+=c[i-1]; for(i=n-1;i>=0;--i) sa[--c[x[y[i]]]]=y[i]; swap(x,y); p=1;x[sa[0]]=0; for(i=1;i<n;++i) x[sa[i]]=(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])?p-1:p++; if(p>=n) break; m=p; }}void getHeight(int n){ int i,j,k=0; for(i=0;i<=n;++i) rank[sa[i]]=i; for(i=0;i<n;++i) { if(k) k--; j=sa[rank[i]-1]; while(s[i+k]==s[j+k]) k++; height[rank[i]]=k; }}int d[maxn][20];void Rmq_init(int n){ for(int i=1;i<=n;++i) d[i][0]=height[i]; for(int j=1;(1<<j)<=n;++j) for(int i=1;i+(1<<j)-1<=n;++i) d[i][j]=min(d[i][j-1],d[i+(1<<(j-1))][j-1]);}int lcp(int L,int R){ L=rank[L];R=rank[R]; if(L>R) swap(L,R); L++; int k=0; while(1<<(k+1)<=R-L+1) k++; return min(d[L][k],d[R-(1<<k)+1][k]);}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); scanf("%s",s); int n=strlen(s); for(int i=1;i<=n;++i) s[i+n]=s[n-i]; s[n]='$'; s[n*2+1]=0; build_sa(n*2+1,300); getHeight(n*2); Rmq_init(n*2); int maxl=1,L=0,R=0,tmp; for(int i=0;i<n;++i) { //奇数 if(i<n-2) { tmp=lcp(i+1,n*2-(i+1)); if(tmp>1&&tmp*2-1>maxl) { maxl=tmp*2-1; L=i+2-tmp; R=i+tmp; } } //偶数 tmp=lcp(i+1,n*2-i); if(tmp*2>maxl) { maxl=tmp*2; L=i-tmp+1; R=i+tmp; } } for(int i=L;i<=R;++i) printf("%c",s[i]); printf("\n"); return 0;}
0 0
- ural 1297 Palindrome 后缀数组
- ural 1297 Palindrome(后缀数组)
- 【后缀数组】【URAL 1297】Palindrome
- URAL 1297 Palindrome 后缀数组
- [URAL 1297]Palindrome(后缀数组)
- Ural 1297 Palindrome (后缀数组)
- URAL 1297 Palindrome(后缀数组)
- URAL 1297 Palindrome (后缀数组)
- URAL 1297 Palindrome <后缀数组+RMQ>
- URAL 1297 Palindrome(最长回文子串:后缀数组)
- URAL 1297(Palindrome,后缀数组)最长回文串
- ural 1297 Palindrome ( 后缀数组 最长回文子串 )
- ural 1297 Palindrome (后缀数组 最长回文)
- URAL - 1297 Palindrome(后缀数组求最长回文子串)
- 【后缀数组|最长回文子串】URAL-1297 Palindrome
- URAL 1297 Palindrome【后缀数组】求最长回文子串
- ural 1297 Palindrome求最长连续回文子串(后缀数组求法)
- 【URAL】1297 Palindrome 【后缀数组+RMQ——求最长回文子串】
- usps shipdate
- FindBugs
- python实现文件夹目录拷贝
- 三元式、四元式
- 进程通信
- ural 1297 Palindrome(后缀数组)
- 10款设计独特的jQuery/CSS3应用插件
- NYOJ 291 LK的数学题
- mysql 开启用户远程操作权限
- codecademy.com之JavaScript学习
- SharedPreferences
- C#根据输入的IP地址查找出对于的城市区域信息
- 处理ios7侧滑手势和scrollview手势的冲突
- 世界上最美丽的公交车站