【题解】回文匹配

题目传送门:【洛谷】回文匹配

回文匹配

题目描述

对于一对字符串 (s1,s2),若 s1 的长度为奇数的子串 (l,r) 满足 (l,r) 是回文的,那么 s1 的“分数”会增加 s2(l,r) 中出现的次数。

现在给出一对 (s1,s2),请计算出 s1 的“分数”。

答案对 232 取模。

输入格式

第一行两个整数,n,m,表示 s1 的长度和 s2 的长度。

第二行两个字符串,s1,s2

输出格式

一行一个整数,表示 s1 的分数。

样例 #1

样例输入 #1

10 2
ccbccbbcbb bc

样例输出 #1

4

样例 #2

样例输入 #2

20 2
cbcaacabcbacbbabacca ba

样例输出 #2

4

提示

【样例解释】

对于样例一:

子串 (1,5)s2 出现了一次,子串 (2,4)s2 出现了一次。

子串 (7,9)s2 出现了一次,子串 (6,10)s2 出现了一次。


【数据范围】

本题采用捆绑测试。

  • 对于 100% 的数据:1n,m3×106,字符串中的字符都是小写字母。

  • 详细的数据范围:

    Subtask 编号 n,m 分值
    1 100 15
    2 103 15
    3 5×103 20
    4 4×105 30
    5 3×106 20

算法1:

有贡献的子串的左端标记1,每次找最大的回文,在左端能遍历的范围内,计算离两边端哪个最近,其距离即贡献值。
i=lrai×(il+1)+i=lrai×(ri+1)

通过观察我们只需要维护aiai×i即可

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int N = 3100010;
int n,m,val[N],p[N],ne[N],sum[N],summ[N];
char s[N],str[N],pp[N];

void init()
{
	for(int i=2,j=0;i<=m;i++)
	{
		while(j&&pp[i]!=pp[j+1]) j=ne[j];
		if(pp[i]==pp[j+1]) j++;	
		ne[i]=j;
	}
}
void kmp()
{
	
	for(int i=1,j=0;i<=n;i++)
	{
		while(j&&s[i]!=pp[j+1]) j=ne[j];
		if(s[i]==pp[j+1]) j++;
		if(j==m)
		{
			j=ne[j];
			val[i-m+1]=1;
		}
	}
}
void manacher()
{
	int mid=0,mr=0;
	for(int i=1;i<=n;i++)
	{
		if(i<mr) p[i]=min(p[mid*2-i],mr-i);
		else p[i]=0;
		while(s[i+p[i]+1]==s[i-p[i]-1]&&i-p[i]-1>=1&&i+p[i]+1<=n)
		{
		    ++p[i];
		} 
		if(i+p[i]>mr)
		{
		    mr=i+p[i];
		    mid=i;
		}
 	}
}
void solve()
{
	long long ans=0;
	for(int i=1;i<=n;i++) 
	{
	    sum[i]=sum[i-1]+val[i];
	    summ[i]=summ[i-1]+val[i]*i;	
	}
	int mid,l,r;
	for(int i=1;i<=n;i++)
	{
		l=i-p[i],r=i+p[i]-m+1;
		if(l>r) continue;
		mid=(l+r)>>1;
		ans+=summ[mid]-summ[l-1]-(sum[mid]-sum[l-1])*(l-1);
	
		if(mid!=r) ans+=(sum[r]-sum[mid])*(r+1)- (summ[r]-summ[mid]);//如果在后半段
		
	}
	long long  mod=pow(2,32);
        printf("%lld\n",ans%mod);	
}

int main()
{
	cin>>n>>m;
	cin>>s+1>>pp+1;
	init();
	manacher();

	kmp();
	solve();
	
	
	return 0;
}

算法2:
双重前缀和

posted @   watasky  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示