BZOJ2565【回文自动机】

来源:互联网 发布:it服务平台 编辑:程序博客网 时间:2024/05/17 03:21

跑两遍PAM.分别找到每个点做为结尾字符和开始字符的最长回文串的长度.

/* I will wait for you */#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;typedef unsigned long long ULL;typedef pair<int,int> PII;const int maxn=500010;const int maxm=1010;const int maxs=26;const int INF=1<<29;const int P=1000000007;const double error=1e-9;inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') f=(ch=='-'?-1:1),ch=getchar();while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();return x*f;}struct pam{pam *fa,*next[maxs];int len,val;}su[maxn],*headf,*heads,*last;int n,pos,cnt,ans,l[maxn],r[maxn];char s[maxn];void init(){s[0]='~',pos=0;headf=&su[++cnt],last=heads=&su[++cnt];headf->fa=heads,heads->len=-1;}void add(int x){pam *per=last;for(pos++;s[pos-per->len-1]!=s[pos];per=per->fa);if(!per->next[x]){pam *now=&su[++cnt];last=per->next[x]=now,now->len=per->len+2;if(per==heads) now->fa=headf;else{for(per=per->fa;s[pos-per->len-1]!=s[pos];per=per->fa);now->fa=per->next[x];}}else last=per->next[x];}int main(){scanf("%s",s+1),n=strlen(s+1);init();for(int i=1;i<=n;i++) add(s[i]-'a'),l[i]=last->len;init();for(int i=1;i<=n/2;i++) swap(s[i],s[n-i+1]);for(int i=1;i<=n;i++) add(s[i]-'a'),r[n-i+1]=last->len;for(int i=1;i<n;i++) ans=max(ans,l[i]+r[i+1]);printf("%d\n",ans);return 0;}
膜拜一下lowsfish的BZOJ rank 1的做法.

每次求出以当前字符String[now]做结尾字符的最长回文串的长度lenth[now].用lenth[now]+lenth[now-lenth[now]]更新答案.

/* I will wait for you */#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;typedef unsigned long long ULL;typedef pair<int,int> PII;const int maxn=100010;const int maxm=1010;const int maxs=26;const int INF=1<<29;const int P=1000000007;const double error=1e-9;inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') f=(ch=='-'?-1:1),ch=getchar();while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();return x*f;}struct pam{pam *fa,*next[maxs];int len;}su[maxn],*headf,*heads,*last;int n,pos,cnt,ans,f[maxn];char s[maxn];void init(){s[0]='~',pos=0;headf=&su[++cnt],last=heads=&su[++cnt];headf->fa=heads,heads->len=-1;}inline void add(int x){pam *per=last;for(pos++;s[pos-per->len-1]!=s[pos];per=per->fa);if(!per->next[x]){pam *now=&su[++cnt];last=per->next[x]=now,now->len=per->len+2;if(per==heads) now->fa=headf;else{for(per=per->fa;s[pos-per->len-1]!=s[pos];per=per->fa);now->fa=per->next[x];}}else last=per->next[x];}int main(){scanf("%s",s+1),n=strlen(s+1),init();for(int i=1;i<=n;i++) add(s[i]-'a'),ans=max(ans,(f[i]=last->len)+f[i-f[i]]);printf("%d\n",ans);return 0;}


0 0
原创粉丝点击