马拉车 [模板]

/*
该模板适用于:
求最长回文子串的长度
求回文子串的总数 
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

int n;
const int maxn = 600005;
char p[maxn],s[2*maxn];
int len[2*maxn];

int init()  //字符串填充 
{
	for(int i=1,j=0;i<=2*n;++j,i+=2)
	{
		s[i]='#';
		s[i+1] = p[j];
	}
	s[0] = '$';
	s[2*n+1]='#';
    s[2*n+2]='@';
    s[2*n+3]='\n';
    return 2*n+1;
}
void manacher(int length)  //马拉车算法 
{  // length为处理后字符串的长度 
	int mx = 0;
	int pp = 0;
	for(int i=1;i<=length;++i)
	{
		if(mx>i)len[i]=min(mx-i,len[2*pp-i]);
		else len[i] = 1;
		while(s[i-len[i]]==s[i+len[i]])len[i]++;
        if(len[i]+i>mx)mx=len[i]+i,pp=i;
	}
}
void solve()  //查找特定结尾的回文子串 
{  //这里要注意理解len数组的含义 
    int m = init();
    memset(len,0,sizeof(len));
    manacher(m);
    ll ans1 = 0;
    ll ans2 = 0;
    ll ans3 = 0;
    for(int i=1;i<=m;++i)
    {
//    	cout<<len[i]<<endl;
    	if(len[i]==1)continue;
    	else if(len[i]==2)
    	{
    		if(s[i]=='k') ++ans1;
    		else if(s[i]=='f') ++ans2;
    		else if(s[i]=='c') ++ans3;
		}
		else if(len[i]>2)
		{
			for(int j=i;j<i+len[i];++j)
			{
				if(s[j]=='k') ++ans1;
    			else if(s[j]=='f') ++ans2;
    			else if(s[j]=='c') ++ans3;
			}
		}
	}
	cout<<ans1<<" "<<ans2<<" "<<ans3<<endl;
}
ll func()   //返回所有回文子串的数量 
{
	int m = init();
    memset(len,0,sizeof(len));
    manacher(m);
    ll ans = 0;
    for(int i=1;i<=m;++i)
		ans += len[i]/2;
	return ans; 
}
int maxstring()  //求最长回文子串 
{
	int m = init();
    memset(len,0,sizeof(len));
    manacher(m);
    int maxlen = -1;
    for(int i=1;i<=m;++i)
    	maxlen = max(maxlen,len[i]);
    return maxlen-1;
}
int main()
{
	int n;
	scanf("%d",&n);
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值