zoj4110 Strings in the Pocket(manacher)
传送: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$开始不同的位置。
- $S$不可以翻转成$T$:就是指$S$串中不同的那一段不可以通过翻转得到$T$,方案数为0。
- $S$与$T$不同的“中间”那一段可以通过翻转得到对应$T$的那一段。这个时候需要向外扩展判断最长可以扩展到的位置。
- $S$与$T$完全相同,这个时候就需要通过manacher来求解整个串内回文子串的个数。
代码:
- 不分奇偶讨论的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)的更多相关文章
- O(n)回文子串(Manacher)算法
O(n)回文子串(Manacher)算法 资料来源网络 参见:http://www.felix021.com/blog/read.php?2040 问题描述: 输入一个字符串,求出其中最大的回文子串. ...
- 【学习笔记】字符串—马拉车(Manacher)
[学习笔记]字符串-马拉车(Manacher) 一:[前言] 马拉车用于求解连续回文子串问题,效率极高. 其核心思想与 \(kmp\) 类似:继承. --引自 \(yyx\) 学姐 二:[算法原理] ...
- HDU 4513 吉哥系列故事——完美队形II(Manacher)
Problem Description 吉哥又想出了一个新的完美队形游戏! 假设有n个人按顺序站在他的面前,他们的身高分别是h[1], h[2] ... h[n],吉哥希望从中挑出一些人,让这些人形成 ...
- 牛客小白月赛13 小A的回文串(Manacher)
链接:https://ac.nowcoder.com/acm/contest/549/B来源:牛客网 题目描述 小A非常喜欢回文串,当然我们都知道回文串这种情况是非常特殊的.所以小A只想知道给定的一个 ...
- 2019浙江省赛 Strings in the Pocket【manacher】
Strings in the Pocket 题目链接 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=6012 题意 给你两个字符 ...
- 2018.06.30 BZOJ 2342: [Shoi2011]双倍回文(manacher)
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MB Description Input 输入分为两行,第一行为一个整数,表示字符串 ...
- ZOJ 4110 Strings in the Pocket (马拉车+回文串)
链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4110 题目: BaoBao has just found two s ...
- Strings in the Pocket(马拉车+字符串判断)
题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=6012 BaoBao has just found two strings ...
- ZOJ4110 Strings in the Pocket(2019浙江省赛)
给出两个字符串,询问有多少种反转方法可以使字符串1变成字符串2. 如果两个串相同,就用马拉车算法找回文串的数量~ 如果两个串不同,从前往后找第一个不同的位置l,从后往前找第二个不同的位置r,反转l和r ...
随机推荐
- leetcode1032
class StreamChecker: def __init__(self, words: 'List[str]'): self.maxLen = 0 self.List = set(words) ...
- Centos7搭建OpenVPN服务器
Windows下同时连接多个VPN的话,需要以管理员身份运行 C:\Program Files\TAP-Windows\bin\addtap.bat 添加虚拟网络适配器 --------------- ...
- linux查看文件夹大小du命令
查看1级(--max-depth=1)目录的大小,并排序 参考 -h或–human-readable 以K,M,G为单位,提高信息的可读性. –max-depth= 超过指定层数的目录后,予以忽略 d ...
- jquery 找同胞系列siblings() ,next() ,nextAll(), nextUntil(), prev(), prevAll(), prevUntil()
注:expr是指可选的参数,包含用于匹配元素的选择器表达式. .siblings(expr) ---查找所有兄弟(包括哥哥和弟弟) .next(expr) ---查找紧挨着的弟弟 .nextAll(e ...
- python入门(七):字符串
1.字符串类型: >>> s="早上好" #str类型的字符串 >>> type(s) <class 'str ...
- DJango 基础(7)
常用查询字段常用类型与模型关系表 知识点: 常用的查询 Field的常用参数 常用的模型字段类型 常用的查询 获取所有记录:rs = User.objects.all()获取第一条数据:rs = Us ...
- 《CSAPP》页表、页命中、缺页
页表 虚拟存储器系统需要某种方法来判定一个虚拟页是否在DRAM的某个地方. 这些功能由操作系统.存储器管理单元(MMU)中的地址翻译硬件和一个存放在物理存储器中的页表数据结构联合提供. 功能 将虚拟页 ...
- CF 317 A. Lengthening Sticks(容斥+组合数学)
传送门:点我 A. Lengthening Sticks time limit per test 1 second You are given three sticks with po ...
- hbase总结~hbase配置和使用
Base配置和使用文档......................................................................................... ...
- windows下Anaconda的安装与配置正解
一.下载anaconda 第一步当然是下载anaconda了,官方网站的下载需要用迅雷才能快点,或者直接到清华大学镜像站下载. 清华大学提供了镜像,从这个镜像下载速度很快,地址: https://mi ...