初涉manacher

一直没有打过……那么今天来找几道题打一打吧

manacher有什么用

字符串的题有一类是专门关于“回文”的。通常来说,这类问题要么和一些dp结合在一起;要么是考察对于manacher(或其他如回文自动机)的理解。

裸的manacher则是解决形如“一个字符串内最长回文串长度”的问题。

一些例题

luoguP3805 【模板】manacher算法

题目描述

给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.

字符串长度为n

输入输出格式

输入格式:

一行小写英文字符a,b,c...y,z组成的字符串S

输出格式:

一个整数表示答案

输入输出样例

输入样例#1:
aaa
输出样例#1:
3

说明

字符串长度len <= 11000000


 

题目分析

注意f[maxn<<1]

 1 #include<bits/stdc++.h>
 2 const int maxn = 11000035;
 3 
 4 int n,f[maxn<<1],mid,ans;
 5 char s[maxn],t[maxn<<1];
 6 
 7 int main()
 8 {
 9     scanf("%s",s+1), t[0] = '!', t[++n] = '#';
10     for (int i=1; s[i]; i++) t[++n] = s[i], t[++n] = '#';
11     for (int i=1, mx=-1; i<n; i++)
12     {
13         if (i < mx) f[i] = std::min(f[(mid<<1)-i], mx-i);
14         else f[i] = 1;
15         for (; t[i+f[i]]==t[i-f[i]]; f[i]++);
16         if (i+f[i] > mx) mx = i+f[i], mid = i;
17         ans = f[i] > ans?f[i]:ans;
18     }
19     printf("%d\n",ans-1);
20     return 0;
21 }

bzoj2565: 最长双回文串

Description

顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同)。
输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分X,Y,(|X|,|Y|≥1)且X和Y都是回文串。

Input

一行由小写英文字母组成的字符串S

Output

一行一个整数,表示最长双回文子串的长度。

Sample Input

baacaabbacabb

Sample Output

12

HINT

样例说明
从第二个字符开始的字符串aacaabbacabb可分为aacaa与bbacabb两部分,且两者都是回文串。
对于100%的数据,2≤|S|≤10^5


 

题目分析

枚举断点,并处理出每一个位置所能够作为起点扩展出的最远位置。

有一些挺好的细节:【BZOJ2565】最长双回文串 Manacher

 1 #include<bits/stdc++.h>
 2 const int maxn = 100035;
 3 
 4 int n,ans,mid,f[maxn<<1],ls[maxn<<1],rs[maxn<<2];
 5 char s[maxn],t[maxn<<1];
 6 
 7 inline void Max(int &x, int y){x = x>y?x:y;}
 8 int main()
 9 {
10     scanf("%s",s+1), t[0] = '!', t[++n] = '#';
11     for (int i=1; s[i]; i++) t[++n] = s[i], t[++n] = '#';
12     for (int i=1, mx=-1; i<=n; i++)
13     {
14         if (i < mx) f[i] = std::min(f[(mid<<1)-i], mx-i);
15         else f[i] = 1;
16         for (; t[i-f[i]]==t[i+f[i]]; f[i]++);
17         if (i+f[i] > mx) mx = i+f[i], mid = i;
18         Max(rs[i-f[i]+1], f[i]-1);
19         Max(ls[i+f[i]-1], f[i]-1);
20     }
21     for (int i=3; i<=n; i+=2) Max(rs[i], rs[i-2]-2);
22     for (int i=n; i>=1; i-=2) Max(ls[i], ls[i+2]-2);
23     for (int i=1; i<=n; i+=2)
24         if (ls[i]&&rs[i]) ans = std::max(ans, ls[i]+rs[i]);
25     printf("%d\n",ans);
26     return 0;
27 }

bzoj3790: 神奇项链

Description

母亲节就要到了,小 H 准备送给她一个特殊的项链。这个项链可以看作一个用小写字
母组成的字符串,每个小写字母表示一种颜色。为了制作这个项链,小 H 购买了两个机器。第一个机器可以生成所有形式的回文串,第二个机器可以把两个回文串连接起来,而且第二个机器还有一个特殊的性质:假如一个字符串的后缀和一个字符串的前缀是完全相同的,那么可以将这个重复部分重叠。例如:aba和aca连接起来,可以生成串abaaca或 abaca。现在给出目标项链的样式,询问你需要使用第二个机器多少次才能生成这个特殊的项链。 

Input

输入数据有多行,每行一个字符串,表示目标项链的样式。 

Output

多行,每行一个答案表示最少需要使用第二个机器的次数。 

Sample Input

abcdcba
abacada
abcdef

Sample Output

0
2
5

HINT

每个测试数据,输入不超过 5行 
每行的字符串长度小于等于 50000 

题目分析

沿用上一题的做法,manacher预处理出最远扩展到的位置。之后就是一个贪心的向远处跳的过程。

(好像预处理暴力也行?)

也挺妙的:【BZOJ3790】神奇项链 Manacher+贪心

 1 #include<bits/stdc++.h>
 2 const int maxn = 50003;
 3 
 4 int n,ans,mid,now,nxt,f[maxn<<1],rs[maxn<<1];
 5 char s[maxn],t[maxn<<1];
 6 
 7 int main()
 8 {
 9     while (scanf("%s",s+1)!=EOF)
10     {
11         memset(f, 0, sizeof f);
12         ans = n = 0, t[0] = '!', t[++n] = '#';
13         for (int i=1; s[i]; i++) t[++n] = s[i], t[++n] = '#';
14         for (int i=1, mx=-1; i<n; i++)
15         {
16             if (i < mx) f[i] = std::min(f[(mid<<1)-i], mx-i);
17             else f[i] = 1;
18             for (; t[i+f[i]]==t[i-f[i]]; f[i]++);
19             if (i+f[i] > mx) mx = i+f[i]-1, mid = i;
20             rs[i-f[i]+1] = i+f[i]-1;
21         }
22 //        now = 1, nxt = 0;
23 //        while (rs[now] < n)
24 //        {
25 //            for (int i=now+1; i<=rs[now]; i++)
26 //                if (rs[i] > rs[nxt]) nxt = i;
27 //            ans++, now = nxt;
28 //        }    //这种是不是不行啊……?
29         now = nxt = rs[1]+2;
30         for (int i=1; i<=n; i+=2)
31         {
32             if (i==now) now = nxt, ans++;
33             nxt = std::max(nxt, rs[i]+2);
34         }
35         printf("%d\n",ans);
36     }
37     return 0;
38 }

 

 

END

转载于:https://www.cnblogs.com/antiquality/p/9820621.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码下载:完整代码,可直接运行 ;运行版本:2022a或2019b或2014a;若运行有问题,可私信博主; **仿真咨询 1 各类智能优化算法改进及应用** 生产调度、经济调度、装配线调度、充电优化、车间调度、发车优化、水库调度、三维装箱、物流选址、货位优化、公交排班优化、充电桩布局优化、车间布局优化、集装箱船配载优化、水泵组合优化、解医疗资源分配优化、设施布局优化、可视域基站和无人机选址优化 **2 机器学习和深度学习方面** 卷积神经网络(CNN)、LSTM、支持向量机(SVM)、最小二乘支持向量机(LSSVM)、极限学习机(ELM)、核极限学习机(KELM)、BP、RBF、宽度学习、DBN、RF、RBF、DELM、XGBOOST、TCN实现风电预测、光伏预测、电池寿命预测、辐射源识别、交通流预测、负荷预测、股价预测、PM2.5浓度预测、电池健康状态预测、水体光学参数反演、NLOS信号识别、地铁停车精准预测、变压器故障诊断 **3 图像处理方面** 图像识别、图像分割、图像检测、图像隐藏、图像配准、图像拼接、图像融合、图像增强、图像压缩感知 **4 路径规划方面** 旅行商问题(TSP)、车辆路径问题(VRP、MVRP、CVRP、VRPTW等)、无人机三维路径规划、无人机协同、无人机编队、机器人路径规划、栅格地图路径规划、多式联运运输问题、车辆协同无人机路径规划、天线线性阵列分布优化、车间布局优化 **5 无人机应用方面** 无人机路径规划、无人机控制、无人机编队、无人机协同、无人机任务分配 **6 无线传感器定位及布局方面** 传感器部署优化、通信协议优化、路由优化、目标定位优化、Dv-Hop定位优化、Leach协议优化、WSN覆盖优化、组播优化、RSSI定位优化 **7 信号处理方面** 信号识别、信号加密、信号去噪、信号增强、雷达信号处理、信号水印嵌入提取、肌电信号、脑电信号、信号配时优化 **8 电力系统方面** 微电网优化、无功优化、配电网重构、储能配置 **9 元胞自动机方面** 交通流 人群疏散 病毒扩散 晶体生长 **10 雷达方面** 卡尔曼滤波跟踪、航迹关联、航迹融合

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值