URAL 1297(后缀数组/Manacher算法)
2016-02-20 20:29
405 查看
(http://acm.hust.edu.cn/vjudge/contest/view.action?cid=105595#problem/F)
题意:寻找最长回文子串
解法:Manacher裸题,也能用后缀数组
题意:寻找最长回文子串
解法:Manacher裸题,也能用后缀数组
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <vector> #include <queue> #include <stack> #include <set> #include <map> #include <queue> //#include <tr1/unordered_set> //#include <tr1/unordered_map> #include <bitset> //#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 #define inf 1e9 #define debug(a) cout << #a" = " << (a) << endl; #define debugarry(a, n) for (int i = 0; i < (n); i++) { cout << #a"[" << i << "] = " << (a)[i] << endl; } #define clr(x, y) memset(x, y, sizeof x) #define ll long long #define ull unsigned long long #define FOR(i,a,b) \ for(i=a;a<b?i<=b:i>=b;a<b?i++:i--) const int maxn = 1000*3+100; char ma[maxn]; int mp[maxn],l; void manacher(char *s,int len){ l=0; ma[l++]='$'; ma[l++]='#'; for(int i=0;i<len;i++) { ma[l++]=s[i]; ma[l++]='#'; } ma[l]=0; int mx=0,id=0; for(int i=0;i<l;i++) { mp[i]=mx>i?min(mp[2*id-i],mx-i):1; while(ma[i+mp[i]]==ma[i-mp[i]]) mp[i]++; if(i+mp[i]>mx) { mx=i+mp[i]; id=i; } } } char s[maxn]; int main() { //freopen("input.txt","r",stdin); while(~scanf("%s",s)) { int len=strlen(s); manacher(s,len); //printf("%s\n",ma); int ans=-1 , pos=inf; for(int i=0;i<l;i++) { if( mp[i] - 1 > ans ) { ans = mp[i]-1; pos = i/2-mp[i]/2; //printf("i %d mp[i] %d\n",i,mp[i]); } } for(int i=0;i<ans;i++) printf("%c",s[i+pos]); printf("\n"); } return 0; }
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <vector> #include <queue> #include <stack> #include <set> #include <map> #include <queue> //#include <tr1/unordered_set> //#include <tr1/unordered_map> #include <bitset> //#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 #define inf 1e9 #define debug(a) cout << #a" = " << (a) << endl; #define debugarry(a, n) for (int i = 0; i < (n); i++) { cout << #a"[" << i << "] = " << (a)[i] << endl; } #define clr(x, y) memset(x, y, sizeof x) #define ll long long #define ull unsigned long long #define FOR(i,a,b) \ for(i=a;a<b?i<=b:i>=b;a<b?i++:i--) const int maxn = 1000*5+100; 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++; if(p>=n) break; m=p; } } 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][20],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]); } }su; char s[maxn]; int main() { //freopen("input.txt","r",stdin); while(~scanf("%s",s)) { int len=strlen(s); s[len]='$'; for(int i=0;i<len;i++) s[2*len-i] = s[i]; s[2*len+1]=0; //printf("%s\n",s); su.n=2*len+2; strcpy(su.s,s); su.build_sa(255); su.getHeight(); su.RMQ_init(); int ans=-1,pos=inf; for(int i=0;i<len;i++) { int t = su.lcp(i,2*len-i); int l = 2*t-1 , ip = i-t+1; //printf("t %d i %d ip %d l %d\n",t,i,ip,l); if( l == ans ) pos=min(pos,ip); else if( l > ans ) { ans=l; pos=ip; } if( i ) { int t = su.lcp(i,2*len-i+1); int l = 2*t,ip = i-t; if( l == ans ) pos=min(pos,ip); else if( l > ans ) { ans=l; pos=ip; //printf("t %d i %d ip %d l %d\n",t,i,ip,l); } } } for(int i=0;i<ans;i++) printf("%c",s[i+pos]); printf("\n"); } return 0; }
相关文章推荐
- 基础练习 字母图形
- Linux dd命令中dsync与fdatasync的区别
- 定义附加项
- ndk配置教程和导入jni的include(可查看c源码)
- java自己主动生成验证码
- MySQL_表操作语句
- sync/fsync/fdatasync的简单比较
- POJ--3617 Best Cow Line
- linux 同步IO: sync、fsync与fdatasync
- python-字典学习笔记
- Httpwatch抓包分析
- hihocoder #1078 : 线段树的区间修改
- MyCat - 背景篇(2)
- 重温C++ 之 重载操作符
- python-元组学习笔记
- 【Python环境】如何使用正确的姿势进行高效Python函数式编程?
- MyCat - 背景篇(1)
- 到底什么是接口
- POJ--3069 Saruman's Army
- Item 55:熟悉一下Boost