Description
母亲节就要到了,小 H 准备送给她一个特殊的项链。这个项链可以看作一个用小写字
母组成的字符串,每个小写字母表示一种颜色。为了制作这个项链,小 H 购买了两个机器。第一个机器可以生成所有形式的回文串,第二个机器可以把两个回文串连接起来,而且第二个机器还有一个特殊的性质:假如一个字符串的后缀和一个字符串的前缀是完全相同的,那么可以将这个重复部分重叠。例如:aba和aca连接起来,可以生成串abaaca或 abaca。现在给出目标项链的样式,询问你需要使用第二个机器多少次才能生成这个特殊的项链。
Input
输入数据有多行,每行一个字符串,表示目标项链的样式。
Output
多行,每行一个答案表示最少需要使用第二个机器的次数。
Sample Input
abcdcba
abacada
abcdef
Sample Output
0
2
5
HINT
每个测试数据,输入不超过 5行
每行的字符串长度小于等于 50000
manacher+贪心
这是我写的manacher第一题啊
这是一个O(n)的找回文串的算法
首先找出以每一位为中心的最长回文子串的区间,问题变成取最少的区间完全覆盖整个区间
排个序贪心就好了。显然是相同个数的区间尽量凑出右边界尽可能大的更优
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<deque> #include<set> #include<map> #include<ctime> #define LL long long #define inf 0x7ffffff #define pa pair<int,int> #define pi 3.1415926535897932384626433832795028841971 using namespace std; inline LL read() { LL x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } inline void write(LL a) { if (a<0){printf("-");a=-a;} if (a>=10)write(a/10); putchar(a%10+‘0‘); } inline void writeln(LL a){write(a);printf("\n");} int len,cnt,tot,now,ans; char ch[100010],s[100010]; int p[100010]; struct srt{int l,r;}a[100010]; bool operator <(srt a,srt b){return a.l<b.l||a.l==b.l&&a.r<b.r;} inline void manacher() { cnt=tot=0;int mx=0,id=0; for (int i=1;i<=len;i++) { s[++cnt]=‘#‘; s[++cnt]=ch[i]; } s[++cnt]=‘#‘; s[0]=‘$‘; for (int i=2;i<cnt;i++) { if (p[id]+id>i)p[i]=min(p[2*id-i],p[id]-(i-id)); else p[i]=1; while (s[i+p[i]]==s[i-p[i]])p[i]++; if (p[i]+i>p[id]+id)id=i; } memset(a,0,sizeof(a)); for (int i=1;i<=cnt;i++) { int res=p[i]-1; int l=i-res,r=i+res; if (l%2)l++;if (r%2)r--; l/=2;r/=2; if (l>r)continue; a[++tot].l=l; a[tot].r=r; } } inline void work() { len=strlen(ch+1); manacher(); sort(a+1,a+tot+1); now=ans=0;int i=1; while (now!=len) { int to=-1; while (a[i].l<=now+1&&i<=tot) to=max(to,a[i].r),i++; now=to;ans++; } printf("%d\n",ans-1); } int main() { while (~scanf("%s",ch+1))work(); }
时间: 2024-10-22 06:49:03