题目
Description
母亲节就要到了,小 H 准备送给她一个特殊的项链。这个项链可以看作一个用小写字母组成的字符串,每个小写字母表示一种颜色。为了制作这个项链,小 H 购买了两个机器。第一个机器可以生成所有形式的回文串,第二个机器可以把两个回文串连接起来,而且第二个机器还有一个特殊的性质:假如一个字符串的后缀和一个字符串的前缀是完全相同的,那么可以将这个重复部分重叠。例如:aba和aca连接起来,可以生成串abaaca或 abaca。现在给出目标项链的样式,询问你需要使用第二个机器多少次才能生成这个特殊的项链。
Input
输入数据有多行,每行一个字符串,表示目标项链的样式。
每个测试数据,输入不超过 5行
每行的字符串长度小于等于 50000
Output
多行,每行一个答案表示最少需要使用第二个机器的次数。
Sample Input
abcdcba
abacada
abcdef
Sample Output
0
2
5
思路:
首先你必须知道基础的$manacher$算法;
那么这一题怎么写呢;
题目可以转化为多少个回文串可以覆盖全部;
很容易想到先把每个回文串的最左节点和最右节点求出来;
然后把每个回文串按左节点排序,如果左节点一样,最好按右节点大的排在前面;
这样就方便找覆盖最大的回文串,并且全部覆盖;
然后再贪心,第一次加入左节点为1并且右节点延伸最远的回文串;
之后加入的数,我们需要中间不留空隙,所以加入的回文串需要与之前的回文串重合(为什么重合,看题!!)或相邻,且向右延伸最远;
如题目样例的第二个:
abacada
第一次加入aba;左节点为1且向右延伸最远的串;
第二次加入aca;与前面串重合且向右延伸最远的串;
第三次加入ada;....................................................
根据题意需要连接两次,所以答案是2;
代码:
#include<bits/stdc++.h> typedef long long ll; using namespace std; inline ll read() { ll a=0,f=1; char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();} return a*f; } char s[1000010],snew[2000010]; ll n,p[2000010]; struct ljq { ll L,R; }f[4000010]; inline ll build() { snew[0]='$';snew[1]='#'; ll j=2,len=strlen(s); for(ll i=0;i<len;i++) { snew[j]=s[i];j++; snew[j]='#'; j++;//* } snew[j]='