传送: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. 模拟器 Unable to execute simctl install Error 117

    ios 模拟器 Unable to execute '"/usr/bin/xcrun" simctl install  "/Users/tt/PAServer/scrat ...

  2. mac os High Sierra 升级错误

    升级mac OS High Sierra错误 已经成功从10.10升级到10.12.8 mac OS  Sierra了.就是升级到10.13报错. you may not install to thi ...

  3. OkHttp 同步异步操作

    OkHttp是一个Java和Android的HTTP和HTTP/2的客户端,负责发送HTTP请求以及接受HTTP响应. 一.使用OkHttp OkHttp发送请求后,可以通过同步或异步地方式获取响应. ...

  4. PowerScript语言基础

    注释: 以 "//" 开头,其后书写注释内容,常用于单行注释. "/-/"中间的部分为注释,便于多行说明. //这是一个单行注释 INTEGER I I = I ...

  5. python import hashllb

    http://www.cnblogs.com/alex3714/articles/5161349.html 用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224 ...

  6. pythonj基础(五)元组和集合

    一,什么是元祖 Python的元组与列表类似,不同之处在于元组的元素不能修改. 元组使用小括号,列表使用方括号. 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可. 1.创建一个空元组 tu ...

  7. 每10秒执行定时任务-crontab

    * * * * * /data/crontab.sh * * * * * sleep 10; /data/crontab.sh * * * * * sleep 20; /data/crontab.sh ...

  8. python04 列表 元祖 字典

    1.list 有序,元素可以被修改 li=[1,2,2,"am","123"] 列表中的元素可以是数字,字符串,列表等等 支持切片,切片结果为列表  li[3] ...

  9. python_day10

    目录: 并发多线程 协程 I/O多路复用(未完成,待续) 一.并发多线程 1.线程简述: 一条流水线的执行过程是一个线程,一条流水线必须属于一个车间,一个车间的运行过程就是一个进程(一个进程内至少一个 ...

  10. 《Miracle_House团队》第一次作业:团队亮相

    Our Team:Miracle_House part 1 团队成员组成: NO.1  汝春瑞   201571030125   (组长) Style:乐观开朗,认真踏实,责任心强,还有就是爱笑.随和 ...