文章目录

  • [Mediocre String Problem](https://codeforces.com/gym/101981)
    • 题目大意
    • 解题思路
    • 代码

Mediocre String Problem

题目大意

给你一个串S,和一个串T,从S中选一个子串做前缀串然后与T的一个前缀串做后缀串组成新的字符串是一个回文串,而且S的子串的长度需要比T的前缀串的长度要长。问你有多少种选取方法。

解题思路

假设我们选取S串的 S [ i : j ] S[i:j] S[i:j]和T串的 T [ 1 : K ] T[1:K] T[1:K]组成的新串是一个回文串,那么 S [ i : j ] S[i:j] S[i:j]的前缀串一定和 T [ 1 : k ] T[1:k] T[1:k]的后缀串是相同的,这是因为,既然新的字符串是一个回文串,那么第一个等于最后一个,第二个等于倒数第二个这个性质推广下去就是上面那个性质了。现在我们 将 S串翻转一下,然后这就变成了 S[i:j] 的前缀等于 T[1:k] 的前缀了 ,但是如果 j 后面还紧挨着一个回文串的话,那么加上回文串也一样可以构成一个新的回文串的。这时候就变成一个模板题了,我们用扩展KMP求lcp,然后用马拉车求回文串,这里用到差分优化下,每次在回文串出现的中点+1,然后在结束的后一个位置-1.
最后的答案就是 这个店的ex[i]*sum[i-1];
可能说的有点乱付价格大佬的博客吧

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1000010;   //字符串长度最大值
int nex[maxn],ex[maxn]; //ex数组即为extend数组
//预处理计算nex数组
char s[maxn*2], str[maxn * 2];
char t[maxn];
int Len[maxn * 2];
// sum数组表示的前面的回文串个数前缀和。
ll sum[maxn];void get_next(char *str)
{int i=0,j,po,len=strlen(str);nex[0]=len;//初始化nex[0]while(str[i]==str[i+1]&&i+1<len)//计算nex[1]i++;nex[1]=i;po=1;//初始化po的位置for(i=2;i<len;i++){if(nex[i-po]+i<nex[po]+po)//第一种情况,可以直接得到nex[i]的值nex[i]=nex[i-po];else//第二种情况,要继续匹配才能得到nex[i]的值{j=nex[po]+po-i;if(j<0)j=0;//如果i>po+nex[po],则要从头开始匹配while(i+j<len&&str[j]==str[j+i])//计算nex[i]j++;nex[i]=j;po=i;//更新po的位置}}
}
//计算extend数组
void exkmp(char *s1,char *s2)
{int i=0,j,po,len=strlen(s1),l2=strlen(s2);get_next(s2);//计算子串的nex数组while(s1[i]==s2[i]&&i<l2&&i<len)//计算ex[0]i++;ex[0]=i;po=0;//初始化po的位置for(i=1;i<len;i++){if(nex[i-po]+i<ex[po]+po)//第一种情况,直接可以得到ex[i]的值ex[i]=nex[i-po];else//第二种情况,要继续匹配才能得到ex[i]的值{j=ex[po]+po-i;if(j<0)j=0;//如果i>ex[po]+po则要从头开始匹配while(i+j<len&&j<l2&&s1[j+i]==s2[j])//计算ex[i]j++;ex[i]=j;po=i;//更新po的位置}}
}
int getstr(int len) {//重定义字符串int k = 0;str[k++] = '@';for (int i = 0; i < len; i++) {str[k++] = '#';str[k++] = s[i];}str[k++] = '#';len = k;str[k] = 0;//字符串尾设置为0,防止越界return k;
}
void manacher(int len) {int mx = 0, id;//mx为最右边,id为中心点int maxx = 0;for (int i = 1; i < len; i++) {if (mx > i) Len[i] = min(mx - i, Len[2 * id - i]);else Len[i] = 1; //超过了就让他等于1,之后再进行查找while (str[i + Len[i]] == str[i - Len[i]]) Len[i]++;if (Len[i] + i > mx) {//更新mxmx = Len[i] + i;id = i;maxx = max(maxx, Len[i]);//最长回文字串长度}// 维护这个点的回文串范围 if(Len[i]){sum[(i+1)/2-1]++;sum[(i+1)/2+Len[i]/2-1]--;}}
}
int main() {scanf("%s",s);scanf("%s",t);int len=strlen(s);for(int i=0;i<len/2;i++){swap(s[i],s[len-i-1]);} exkmp(s,t);int k=getstr(len);manacher(k);ll ans=0;for(int i=1;i<len;i++){sum[i]+=sum[i-1];ans=ans+ex[i]*sum[i-1];}cout<<ans<<"\n";return 0;
}

Mediocre String Problem(马拉车+扩展KMP)相关推荐

  1. M - Mediocre String Problem( 扩展KMP + Manacher + 差分 )

    M - Mediocre String Problem( 扩展KMP + Manacher + 差分 ) 题意:给出一个串S,和一个串T. 要求 从S串中取一个子串,后面接上T串的一个前缀 组成一个结 ...

  2. Gym - 101981 Problem M. Mediocre String Problem (扩展KMP + Manacher)

    Problem M. Mediocre String Problem 题目链接:https://vjudge.net/problem/Gym-101981M 题目大意:给出两个串S,T,从S中选择 i ...

  3. Mediocre String Problem (2018南京M,回文+LCP 3×3=9种做法 %%%千年好题 感谢Grunt大佬的细心讲解)...

    layout: post title: Mediocre String Problem (2018南京M,回文+LCP 3×3=9种做法 %%%千年好题 感谢"Grunt"大佬的细 ...

  4. Problem M. Mediocre String Problem

    Problem M. Mediocre String Problem(马拉车+拓展KMP) 题意:给一个S串一个T串, 问有多少个F(i, j, k),F(i, j, k) 的定义是S串选个下标i~j ...

  5. ACM-ICPC2018南京赛区 Mediocre String Problem

    Mediocre String Problem 题解: 很容易想到将第一个串反过来,然后对于s串的每个位置可以求出t的前缀和它匹配了多少个(EXKMP 或者 二分+hash). 然后剩下的就是要处理以 ...

  6. 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 ...

  7. Gym_101981M Mediocre String Problem(exkmp+manachar)

    Mediocre String Problem time limit per test:1 seconds memory limit per test:256 megabytes Problem De ...

  8. 2018 ICPC 南京 M. Mediocre String Problem(ExKMP + Manacher / ExKMP+回文树)

    2018 ICPC 南京 全文见:https://blog.csdn.net/qq_43461168/article/details/112796538 M. Mediocre String Prob ...

  9. 2018 ICPC 南京 M. Mediocre String Problem (马拉车+扩展kmp)

    题链:https://nanti.jisuanke.com/t/A2150 题意:给出两个串S,T.求S的子串接上T的前缀子串(S子串的长度要大于T前缀子串的长度.)所能组成的回文串的个数. 思路:我 ...

最新文章

  1. Python:新浪网分类资讯爬虫
  2. 工欲善其事,必先利其器。如何玩转 VS Code?
  3. Amber计算MM能量
  4. 解决overfitting的方法
  5. hbase shell
  6. 三、oracle 用户管理一
  7. QQ窗口的控制,同步异步打开360网盘,控制360网盘窗口的移动
  8. Android开发中EditText获得焦点弹出输入框改变屏幕布局的问题
  9. volatile指令重排_有多少人面试栽到Volatile上?面试问题都总结到这儿了
  10. 使用dbUnit,JSON,HSQLDB和JUnit规则进行数据库单元测试
  11. python里写在文件的指定行_python文件操作如何写在指定的行
  12. 三星电视显示服务器无响应,三星电视网络电视看不了是怎么回事?
  13. 服务器怎么跑python_在Linux服务器上跑Python Unet程序
  14. Android与Windows Socket通信,TLS双向认证
  15. com.alibaba.druid.sql.parser.ParserException: syntax error, QUES %,
  16. 色纯度(purity)主波长(WD)计算软件
  17. 个人陈述怎么写计算机专业自招,自主招生个人陈述范文
  18. 完美解决Mac无法写入NTFS硬盘——Mounty for NTFS
  19. vue使用高德地图-进行显示地图和查询天气
  20. 小米刷机OTA、 Recovery、 FASTBOOT三种方法直接的区别和联系

热门文章

  1. 计算机毕业设计ssm师生交流平台cb59e系统+程序+源码+lw+远程部署
  2. 多路由器串联以及动态获取ip
  3. 分别定义Teacher(教师)类和Cadre(干部)类
  4. 如何mysql数据库输出为jone_我们可以通过单个MySQL查询获得记录“ Jone Deo”或“ Deo Jone”吗?...
  5. Java分页代码(JFIS)
  6. 计算机冷启动和热启动的区别
  7. pygame游戏实例入门
  8. java .lck文件_关于Java日志log.lck文件的出现原因和关闭方法
  9. 普通人找到比打工还赚钱的副业,只要这三招!
  10. imgPreview 图片预览、国外网址