传送:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=6012

题意:给定两个串$S$和$T$,可以翻转$S$串中的任意一个子段,得到$T$。问,可以翻转的方案书有多少?

数据范围:多组数据。$1\leq|S|\leq2\times10^5$,$\sum|S|\leq2\times10^7$。

分析:很明显需要分类讨论$S$与$T$比较的各种情况。

首先需要判断$S$串从左和从右找到与$T$开始不同的位置。

  1. $S$不可以翻转成$T$:就是指$S$串中不同的那一段不可以通过翻转得到$T$,方案数为0。
  2. $S$与$T$不同的“中间”那一段可以通过翻转得到对应$T$的那一段。这个时候需要向外扩展判断最长可以扩展到的位置。
  3. $S$与$T$完全相同,这个时候就需要通过manacher来求解整个串内回文子串的个数。

代码:

  1. 不分奇偶讨论的manacher
 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e6+;
char S[maxn],T[maxn],s[maxn*];
int p[maxn*],len;
int init(){
s[]=s[]='#';
for (int i=;i<len;i++){
s[i*+]=S[i];
s[i*+]='#';
}
len=len*+;
s[len]=;
}
void manacher(){
int id,mx=;
for (int i=;i<len;i++){
if(i<mx) p[i]=min(p[(id<<)-i],p[id]+id-i);
else p[i]=;
while (s[i-p[i]]==s[i+p[i]]) p[i]++;
if (mx<i+p[i]){
id=i;mx=i+p[i];
}
}
}
int main(){
int t; scanf("%d",&t);
while (t--){
scanf("%s",S);
scanf("%s",T);
len=strlen(S);
int l=,r=len-; ll ans=;
while (S[l]==T[l] && l<len) l++;
while (S[r]==T[r] && r>=) r--;
if (l==r){printf("0\n"); continue;}
if (l<len){
ans=;
for (int i=l;i<=r;i++)
if (S[i]!=T[l+r-i]){
ans=; break;
}
if (ans){
ans=;
l--;r++;
while (l>= && r<len && S[l]==T[r] && S[r]==T[l]){
l--;r++;ans++;
}
}
printf("%d\n",ans);
}
else{
init();
manacher(); ans=;
for (int i=;i<len;i++) ans+=(p[i]/);
printf("%lld\n",ans-);
}
}
return ;
}

  2.分奇偶讨论的manacher

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e6+;
char S[maxn],T[maxn];
int odd[maxn],eve[maxn],len;
ll manacher(){
int l=-,r=-,x;
ll ans=;
for(int i=;i<len;i++)
{
if (i>r) x=;
else x=min(odd[l+r-i],r-i);
while (i-x>= && i+x<len && S[i-x]==S[i+x]) x++;
odd[i]=x;
ans+=x;
if (i+x->r) {r=i+x-;l=i-x+;}
}
l=r=-;
for(int i=;i<len;i++)
{
if(i>r) x=;
else x=min(eve[l+r-i+],r-i+);
while (i-x->= && i+x<len && S[i-x-]==S[i+x]) x++;
eve[i]=x;
ans+=x;
if (i+x>=r) {l=i-x;r=i+x-;}
}
return ans;
}
int main(){
int t; scanf("%d",&t);
while (t--){
scanf("%s",S);
scanf("%s",T);
len=strlen(S);
int l=,r=len-; ll ans=;
while (S[l]==T[l] && l<len) l++;
while (S[r]==T[r] && r>=) r--;
if (l==r){printf("0\n"); continue;}
if (l<len){
ans=;
for (int i=l;i<=r;i++)
if (S[i]!=T[l+r-i]){
ans=; break;
}
if (ans){
ans=;
l--;r++;
while (l>= && r<len && S[l]==T[r] && S[r]==T[l]){
l--;r++;ans++;
}
}
printf("%d\n",ans);
}
else{
ans=manacher();
printf("%lld\n",ans);
}
}
return ;
}

zoj4110 Strings in the Pocket(manacher)的更多相关文章

  1. O(n)回文子串(Manacher)算法

    O(n)回文子串(Manacher)算法 资料来源网络 参见:http://www.felix021.com/blog/read.php?2040 问题描述: 输入一个字符串,求出其中最大的回文子串. ...

  2. 【学习笔记】字符串—马拉车(Manacher)

    [学习笔记]字符串-马拉车(Manacher) 一:[前言] 马拉车用于求解连续回文子串问题,效率极高. 其核心思想与 \(kmp\) 类似:继承. --引自 \(yyx\) 学姐 二:[算法原理] ...

  3. HDU 4513 吉哥系列故事——完美队形II(Manacher)

    Problem Description 吉哥又想出了一个新的完美队形游戏! 假设有n个人按顺序站在他的面前,他们的身高分别是h[1], h[2] ... h[n],吉哥希望从中挑出一些人,让这些人形成 ...

  4. 牛客小白月赛13 小A的回文串(Manacher)

    链接:https://ac.nowcoder.com/acm/contest/549/B来源:牛客网 题目描述 小A非常喜欢回文串,当然我们都知道回文串这种情况是非常特殊的.所以小A只想知道给定的一个 ...

  5. 2019浙江省赛 Strings in the Pocket【manacher】

    Strings in the Pocket 题目链接 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=6012 题意 给你两个字符 ...

  6. 2018.06.30 BZOJ 2342: [Shoi2011]双倍回文(manacher)

    2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MB Description Input 输入分为两行,第一行为一个整数,表示字符串 ...

  7. ZOJ 4110 Strings in the Pocket (马拉车+回文串)

    链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4110 题目: BaoBao has just found two s ...

  8. Strings in the Pocket(马拉车+字符串判断)

    题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=6012 BaoBao has just found two strings ...

  9. ZOJ4110 Strings in the Pocket(2019浙江省赛)

    给出两个字符串,询问有多少种反转方法可以使字符串1变成字符串2. 如果两个串相同,就用马拉车算法找回文串的数量~ 如果两个串不同,从前往后找第一个不同的位置l,从后往前找第二个不同的位置r,反转l和r ...

随机推荐

  1. leetcode234

    /** * Definition for singly-linked list. * public class ListNode { * public int val; * public ListNo ...

  2. Django02-路由系统urls

    一.路由配置系统(URLconf) 分为:静态路由动态路由 1.URL配置 URL配置(URLconf)就像Django所支撑网站的目录.它的本质是URL与该URL调用的视图函数之间的映射表 语法: ...

  3. docker 入门第一步

    docker 安装 利用yum 安装 yum 源更新到最新版本,命令: yum update 需要安装工具 net-tools 命令:yum  install -y net-tools 配置docke ...

  4. java.lang.String (JDK1.8)

    String类实现了java.io.Serializable, Comparable<String>, CharSequence这三个interface. 看了下这三个interface中 ...

  5. 原生js实现Base64编码解码

    注:ie10+ var str = window.btoa("liusong"); console.log(str); var s = window.atob("bGl1 ...

  6. crontab命令详解 含启动/重启/停止

    linux 系统则是由 cron (crond) 这个系统服务来控制的.Linux 系统上面原本就有非常多的计划性工作,因此这个系统服务是默认启动的.另 外, 由于使用者自己也可以设置计划任务,所以, ...

  7. mencached

    是一个免费开源的,分布式内存对象缓存系统数据库. 是一个非关系型数据库形式,属于NOSQL NOT OLNY SQL ,不仅仅是关系数据库 它属于K V 存储 KEY VALUE 相对应的存储 KEY ...

  8. win10 使用tsmmc.msc 提示无法创建管理单元

    win10下面直接使用tsmmc.msc,会"提示无法创建管理单元",之前刚装的win10的时候,解决过一次,但昨天系统更新,打过补丁后,又不能用了. 网上的大部份解决办法,如注册 ...

  9. Failed to connect to 127.0.0.1 port 1080: Connection refused package 问题解决方法

    错误: fatal: unable to access 'https://github.com/******': Failed to connect to 127.0.0.1 port 1080: C ...

  10. MAC系统上不能调试华为手机

    调试问题: 使用MACOS会发现在android 开发环境完整的情况下,接入MOTO,SAMSUNG,HTC,ZTE等手机都可以自动识别,并可以在DDMS中查看LOGCAT,唯独华为的手机不可识别.U ...