首页 > 其他分享 >回文子串对(扩展kmp-kmp与回文子串)

回文子串对(扩展kmp-kmp与回文子串)

时间:2022-10-25 10:02:12浏览次数:64  
标签:子串 int long MAXN kmp include 回文


Problem 1 回文子串对(manacher.cpp/c/pas)

【题目描述】

给定一长度为n的小写字母串,求有多少对回文子串,它们的交集非空。

一对回文子串的交集非空:[a,b]、[c,d](a≠c或b≠d)为2个回文子串,且[a,b]∩[c,d]≠∅。

【输入格式】

第一行一个整数n表示串长。

第二行长度为n的小写字母串。

【输出格式】

输出一个整数表示答案,答案对1000000007取模。

【样例输入】

4

babb

【样例输出】

6

【数据范围】

对于30%的数据,n<=1000

另有10%的数据,串里仅含一种字母。

对于100%的数据,n<=2*10^6

 

找到最前面的max(r[j]+j),映射过去

设r[i]表示以i点为中心点的最长回文子串

则如图:

回文子串对(扩展kmp-kmp与回文子串)_#include



#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<functional>
#include<algorithm>
using namespace std;
#define F (1000000007)
#define MAXN (2000000+10)
using namespace std;
long long r[MAXN],n,L[MAXN][2],R[MAXN][3];
char s[MAXN];
int main()
{
freopen("manacher.in","r",stdin);
freopen("manacher.out","w",stdout);
scanf("%d%s",&n,s+1);
memset(r,0,sizeof(r));
memset(L,0,sizeof(L));
memset(R,0,sizeof(R));
int j=0;
for (int i=1;i<=n;i++)
{
if (r[j]+j>i) r[i]=min(r[j-(i-j)],j+r[j]-i);
while (i-r[i]>1&&i+r[i]<n&&s[i-r[i]-1]==s[i+r[i]+1]) r[i]++;
if (r[i]+i>r[j]+j) j=i;
L[i-r[i]][0]+=1;
L[i+1][0]-=1;
R[i][0]++;
R[i+r[i]+1][0]--;
}
// for (int i=1;i<=n;i++) cout<<r[i]<<' ';cout<<endl;
j=0;memset(r,0,sizeof(r));
for (int i=1;i<n;i++)
{
if (r[j]+j>i) r[i]=min(r[j-(i-j)],j+r[j]-i);
while (i-r[i]>0&&i+r[i]<=n&&s[i+1-r[i]-1]==s[i+r[i]+1]) r[i]++;
if (r[i]+i>r[j]+j) j=i;
L[i+1-r[i]][0]+=1;
L[i+1][0]-=1;
R[i+1][0]++;
R[i+r[i]+1][0]--;
}
/*
for (int i=1;i<=n;i++) cout<<L[i][0]<<' ';cout<<endl;
for (int i=1;i<=n;i++) cout<<R[i][0]<<' ';cout<<endl;
*/
for (int i=1;i<=n;i++) L[i][1]=L[i][0]+L[i-1][1];
for (int j=1;j<=2;j++)
for (int i=1;i<=n;i++)
R[i][j]=R[i-1][j]+R[i][j-1];
long long ans=0;
for (int i=1;i<=n;i++)
ans=(ans+L[i][1]*R[i-1][2])%F;
long long tot=0;
if (R[n][2]%2) tot=(((R[n][2]-1)/2)%F)*((R[n][2])%F)%F;
else tot=(((R[n][2])/2)%F)*((R[n][2]-1)%F)%F;
// cout<<tot<<' '<<ans<<endl;

cout<<((tot-ans+F)%F)<<endl;
return 0;
}








标签:子串,int,long,MAXN,kmp,include,回文
From: https://blog.51cto.com/u_15724837/5794013

相关文章

  • 代码随想录Day9 KMP算法
    LeetCode 剑指offer 58 左旋转字符串字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符......
  • 7-2 队列实现回文
    编写一个程序判断一个字符串是否是回文。回文是指一个字符序列以中间字符为基准两边字符完全相同,如字符序列"ABCDEDCBA"就是回文,而字符序列"ABCDEDBAC"就不是回文。空格不......
  • 7-1 栈实现回文
    输入一个字符串,判断该字符串是否为回文。回文就是字符串中心对称,从左向右读和从右向左读的内容是一样的。(不含空格)#include<bits/stdc++.h>usingnamespacestd;#defin......
  • 5. 最长回文子串
    给你一个字符串s,找到s中最长的回文子串。示例1:输入:s="babad"输出:"bab"解释:"aba"同样是符合题意的答案。示例2:输入:s="cbbd"输出:"bb"提示:1<=s.length<=10......
  • 【Python】第3章-21 判断回文字符串
    输入一个字符串,判断该字符串是否为回文。回文就是字符串中心对称,从左向右读和从右向左读的内容是一样的。输入格式:输入在一行中给出一个不超过80个字符长度的、以回车结......
  • #yyds干货盘点# LeetCode 腾讯精选练习 50 题: 回文数
    题目:给你一个整数x,如果x是一个回文整数,返回true;否则,返回false。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121是回文,而123不是。 示例1:输入......
  • 最长回文子串
    输入:s="babad"输出:"bab"解释:"aba"同样是符合题意的答案。classSolution:deflongestPalindrome(self,s:str)->str:palindrome=""#中心......
  • #yyds干货盘点# LeetCode 腾讯精选练习 50 题:最长回文子串
    题目:给你一个字符串s,找到s中最长的回文子串。 示例1:输入:s="babad"输出:"bab"解释:"aba"同样是符合题意的答案。示例2:输入:s="cbbd"输出:"bb"代码实现:publicclassSo......
  • 基础结构:链表 回文链表
    1.问题描述给你一个单链表的头节点head,请你判断该链表是否为回文链表。如果是,返回true;否则,返回false。示例1:image.jpg输入:head=[1,2,2,1]输出:true示例2:imag......
  • leetcode 最长回文子串
    constcountSubstrings=(s)=>{conststrLen=s.length;letnumOfPalindromicStr=0;//初始化一个二维数组letdp=Array.from(Array(strLen),()=>A......