模板 manacher算法

字符串的最长回文串长度O(N)算法。

主要是利用了回文串的对称性,利用已有的子串更新答案。

然后拓展答案。

详细讲解还是问dalao吧

我是蒟蒻QAQ

代码(luoguP3805)

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using std::min;
 5 using std::max;
 6 char a[20000000];
 7 int l[100000000];
 8 int f[100000000];
 9 int cnt;
10 int ans;
11 int main()
12 {
13     scanf("%s",a+1);
14     int len=strlen(a+1);
15     l[0]='#';
16     for(int i=1;i<=len;i++)
17     {
18         l[++cnt]='#';
19         l[++cnt]=a[i];
20     }
21     l[++cnt]='#';
22     
23     f[1]=1;
24     int mx=1;
25     for(int i=2;i<=cnt;i++)
26     {
27         f[i]=min(f[mx*2-i],f[mx]+mx-i);
28         while(i+f[i]<=cnt&&l[i+f[i]]==l[i-f[i]])
29             f[i]++;
30         if(i+f[i]>mx+f[mx])
31             mx=i;
32         ans=max(ans,f[i]-1);
33     }
34     printf("%d\n",ans);
35     return 0;
36 }

 poj3974

回文串裸题。

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using std::min;
 5 using std::max;
 6 char a[2000000];
 7 int l[5000000];
 8 int f[5000000];
 9 int mx;
10 int cs;
11 int main()
12 {
13     while(1)
14     {
15         cs++;
16         scanf("%s",a+1);
17         int len=strlen(a+1);
18         if(a[1]=='E')
19             return 0;
20         int cnt=0;
21         l[cnt]='#';
22         for(int i=1;i<=len;i++)
23         {
24             l[++cnt]='#';
25             l[++cnt]=a[i];
26         }
27         mx=1;
28         f[0]=0;
29         f[1]=1;
30         l[++cnt]='#';
31         int ans=0;
32         for(int i=2;i<=cnt;i++)
33         {
34             f[i]=min(f[mx]+mx-i,f[mx*2-i]);
35             while(i+f[i]<=cnt&&l[f[i]+i]==l[i-f[i]])
36                 f[i]++;
37             if(f[i]+i>f[mx]+mx)
38                 mx=i;
39             ans=max(ans,f[i]-1);
40         }
41         printf("Case %d: %d\n",cs,ans);
42     }
43     return 0;
44 }

 

转载于:https://www.cnblogs.com/blog-Dr-J/p/9676185.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值