Gym - 101981 Problem M. Mediocre String Problem (扩展KMP + Manacher)
Problem M. Mediocre String Problem
题目链接:https://vjudge.net/problem/Gym-101981M
题目大意:给出两个串S,T,从S中选择 i~j 的子串,再从T中选择前缀 1~k 接在S的子串后面 组成一个新字符串,要求 j-i+1>k,问能构成的新串中是回文串的个数
思路:因为要求j-i+1>k,即S中选择的子串x比T中选择的子串y长,且组成的新串是回文串,那么可以知道串y与串x的长度相等的前缀是相反的,并且x串的后面部分是回文串,也就是新串的中间部分(去掉后面的串y,和前面与y长度相同的前缀)。那么把S串反过来后,S要选择的子串x就是 长度与y相等的后缀与y相同,且前面部分是回文串。那么现在就可以知道要怎么做了
先将S串反转,然后用扩展KMP求T与S的每一个后缀的最长公共前缀extend,然后再用Manacher求出S串的cn,cn[ i ] 表示S串中以第i位为右端点的回文子串的个数。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1000010;
char s[N],t[N],ma[N*2];
int nex[N],extend[N],r[N*2],cn[N];
void getnex(char x[],int m)
{nex[0]=m;int j=0;while(j+1<m&&x[j]==x[j+1])j++;nex[1]=j;int k=1;for(int i=2;i<m;i++){int p=nex[k]+k-1;int L=nex[i-k];if(i+L<p+1) nex[i]=L;else{j=max(0,p-i+1);while(i+j<m&&x[i+j]==x[j]) j++;nex[i]=j;k=i;}}
}
void exkmp(char x[],int m,char y[],int n) //扩展KMP模板
{getnex(x,m);int j=0;while(j<n&&j<m&&x[j]==y[j]) j++;extend[0]=j;int k=0;for(int i=1;i<n;i++){int p=extend[k]+k-1;int L=nex[i-k];if(i+L<p+1) extend[i]=L;else{j=max(0,p-i+1);while(i+j<n&&j<m&&y[i+j]==x[j]) j++;extend[i]=j;k=i;}}
}
void Manacher(char s[],int len)
{memset(r,0,sizeof(r));int l=0;ma[l++]='@',ma[l++]='#';for(int i=0;i<len;i++){ma[l++]=s[i];ma[l++]='#';}int mx=0,id;for(int i=0;i<l;i++){if(mx>i) r[i]=min(mx-i,r[id*2-i]);else r[i]=1;for(;ma[i-r[i]]==ma[i+r[i]];r[i]++);if(r[i]+i>mx){mx=i+r[i];id=i;}}for(int i=2;i<=len*2;i++) //差分记录{if(r[i]>2)cn[i/2]++,cn[(i/2)+(r[i]-1)/2]--;}//cn[i]表示s串中以第i位为右端点的回文子串的个数cn[0]=1;//所有单个字符都是回文串for(int i=1;i<len;i++) cn[i]+=cn[i-1]; //前缀和为个数
}
int main()
{scanf("%s%s",s,t);int l1=strlen(s),l2=strlen(t);reverse(s,s+l1);exkmp(t,l2,s,l1);Manacher(s,l1);ll ans=0;for(int i=1;i<l1;i++)ans+=(ll)extend[i]*cn[i-1];printf("%lld\n",ans);return 0;
}
Gym - 101981 Problem M. Mediocre String Problem (扩展KMP + Manacher)相关推荐
- Problem M. Mediocre String Problem(Z 函数 + PAM)
Problem M. Mediocre String Problem 给定两个串s,ts, ts,t,要求有多少不同的三元组(i,j,k)(i, j, k)(i,j,k),满足: 1≤i≤j≤∣s∣1 ...
- Problem M. Mediocre String Problem
Problem M. Mediocre String Problem(马拉车+拓展KMP) 题意:给一个S串一个T串, 问有多少个F(i, j, k),F(i, j, k) 的定义是S串选个下标i~j ...
- 2018ICPC南京 Problem M. Mediocre String Problem(回文串,马拉车,扩展KMP)
题意: 给你两个字符串 s , t s,t s,t,要求从 s s s中找到一个子串和 t t t的一个前缀拼起来,结果要是回文串.求多少种拼法. 思路: 借此题复习了一下字符串算法. 首先 s s ...
- Mediocre String Problem(马拉车+扩展KMP)
文章目录 [Mediocre String Problem](https://codeforces.com/gym/101981) 题目大意 解题思路 代码 Mediocre String Probl ...
- M - Mediocre String Problem( 扩展KMP + Manacher + 差分 )
M - Mediocre String Problem( 扩展KMP + Manacher + 差分 ) 题意:给出一个串S,和一个串T. 要求 从S串中取一个子串,后面接上T串的一个前缀 组成一个结 ...
- Mediocre String Problem (2018南京M,回文+LCP 3×3=9种做法 %%%千年好题 感谢Grunt大佬的细心讲解)...
layout: post title: Mediocre String Problem (2018南京M,回文+LCP 3×3=9种做法 %%%千年好题 感谢"Grunt"大佬的细 ...
- Gym_101981M Mediocre String Problem(exkmp+manachar)
Mediocre String Problem time limit per test:1 seconds memory limit per test:256 megabytes Problem De ...
- ACM-ICPC2018南京赛区 Mediocre String Problem
Mediocre String Problem 题解: 很容易想到将第一个串反过来,然后对于s串的每个位置可以求出t的前缀和它匹配了多少个(EXKMP 或者 二分+hash). 然后剩下的就是要处理以 ...
- 2018 ICPC 南京 M. Mediocre String Problem(ExKMP + Manacher / ExKMP+回文树)
2018 ICPC 南京 全文见:https://blog.csdn.net/qq_43461168/article/details/112796538 M. Mediocre String Prob ...
最新文章
- UICollectionView入门--使用系统UICollectionViewFlowLayout布局类
- basys2数码管共阳还是共阴_数据选择器Multiplexer || 数码管动态显示 ||实现逻辑函数 || 重难考点 || 数电...
- 微信小程序一定要用https的理由,小程序使用HTTPS链接分析
- Android开发之Java基础JVM和ClassLoader以及类加机制面试题
- 第19章,运维自动化之系统安装
- c++双向列表释放_至为芯科技IP5356集成20W输出和双路TYPE-C快充输出,适用于充电宝/移动电源方案...
- Linux 系统启动
- Android之ViewFlipper使用详解
- 项目管理ppt_干货:腾讯内部项目管理PPT!
- 编程中的幂等性(一):http幂等性
- 怎么用spss做冗余分析_【攻略】手把手教你怎么用SPSS做统计分析
- RFC2544优化步长测试——信而泰网络测试仪实操
- 三菱FX3U PLC 位置式PID算法(ST语言)
- oracle 2019 ocp,2019 OCP简介
- mysql修改字段设置_在mysql中,如何改变列声明.
- Jetson AGX xavier测试六叶树Usb转Can卡通信记录笔记
- 【SVM】支持向量机数学公式
- CEF 拦截URL,重定向新的网址
- 【小记】每日学习(1)
- Burpsuite 重要插件