1. 程式人生 > 資訊 >黑鯊 3 系列推送 JOYUI 12.5 :基於 MIUI 12.5,新增鯊鯊醬智慧助手

黑鯊 3 系列推送 JOYUI 12.5 :基於 MIUI 12.5,新增鯊鯊醬智慧助手

1. manacher 馬拉車

P3805 【模板】manacher 演算法

思路

  1. 迴文串長度有奇有偶,奇迴文串有對稱中心,那偶迴文串呢,所以我們就在每兩個字串之間加一個#,再在整個串前面加一個 % ,這樣奇偶串就可以用按一種方法處理了,比如abcd --> %a#b#c#d#
  2. 我們可以用O(n) 求出r陣列,r[i]是以i為對稱中心的迴文串半徑(長度包括i),令mx是迴文串覆蓋的最右邊界的右邊一位,p是覆蓋最右邊界的迴文串的對稱中心,這時我們要求r[i],暴力會TLE,當p<mx時,我們考慮r[i]可以從r[2 * p - i] 處已確認對稱的部分轉移過來,r[i]=min (mx-p,r[ 2 * p - i ]),之後繼續嘗試暴力向外拓展,看r[i]是否能增大

code

#include<bits/stdc++.h>
#define N 22000010
#define mod 998244353
#define int long long
using namespace std;
int n,ans;
int r[N];
char a[N];
template<class T> inline void read(T &x)
{
	x=0;int g=1;char s=getchar();
	for (;s<'0'||s>'9';s=getchar()) if (s=='-') g=-1;
	for (;s>='0'&&s<='9';s=getchar()) x=(x<<1)+(x<<3)+(s^48);
	x*=g;
}
signed main()
{
	int i,j,op,x,y,z;
	scanf("%s",a+1);
	n=strlen(a+1);
	for (i=n;i;i--) a[2*i]=a[i],a[2*i+1]='#';a[1]='#';a[0]='$';	
	int p=1,mx=1;
	n=2*n+1;
	for (i=1;i<=n;i++)
	{
		if (mx<=i) r[i]=1;
		else r[i]=min(mx-i,r[2*p-i]);
		while(a[i+r[i]]==a[i-r[i]]) r[i]++;
		if (i+r[i]>mx)
		{
			mx=i+r[i];p=i;
		}	
		ans=max(ans,r[i]);
	}
	printf("%lld\n",ans-1);
	return 0;
}