来自FallDream的博客,未经允许,请勿转载,谢谢。


JYY有两个长度均为N的字符串A和B。
一个“扭动字符串S(i,j,k)由A中的第i个字符到第j个字符组成的子串与B中的第j个字符到第k个字符组成的子串拼接而成。
比如,若A=’XYZ’,B=’UVW’,则扭动字符串S(1,2,3)=’XYVW’。
JYY定义一个“扭动的回文串”为如下情况中的一个:
1.A中的一个回文串;
2.B中的一个回文串;
3.或者某一个回文的扭动字符串S(i,j,k)
现在JYY希望找出最长的扭动回文串。
n<=10^5
 
不难证明最长的扭动回文串是由一个中心的最长的回文串向两边延伸得到的。
所以先马拉车,然后二分+哈希判断即可。
还要判断一下两个串分别对称的情况。
#include<iostream>
#include<cstdio>
#include<vector>
#define MN 200000
#define rint register int
#define getchar() (*S++)
char BB[<<],*S=BB;
using namespace std;
inline int read()
{
int x = ; char ch = getchar();
while(ch < '' || ch > '') ch = getchar();
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return x;
}
inline char Getchar()
{
char c;
do c=getchar(); while(c<'A'||c>'Z');
return c;
} int n,mx,pos,Lt[MN+],Rt[MN+],ans=;
unsigned int f[MN+],F[MN+],pw[MN+];
char A[MN+],B[MN+]; int Solve(int Lt,int Rt)
{
int l=,r=min(Lt,n-Rt+),mid,ans=;
while(l<=r)
{
mid=l+r>>;
unsigned int ha1,ha2;
ha1=f[Lt-mid+]-pw[mid]*f[Lt+];
ha2=F[Rt+mid-]-pw[mid]*F[Rt-];
if(ha1==ha2) ans=mid,l=mid+;
else r=mid-;
}
return ans;
} int main()
{
fread(BB,,<<,stdin);
n=read();pw[]=;
for(rint i=;i<=n;++i) A[i<<]=Getchar(),pw[i]=pw[i-]*;
for(rint i=;i<=n;++i) B[i<<]=Getchar();
for(rint i=;i<=n+;++i) A[i*-]=B[i*-]=']';
mx=,pos=;n=n*+;
for(rint i=n;i;--i) f[i]=f[i+]*+A[i]-'A'+;
for(rint i=;i<=n;++i) F[i]=F[i-]*+B[i]-'A'+;
for(rint i=;i<=n;++i)
{
if(i<=mx) Lt[i]=min(mx-i+,Lt[*pos-i]);
else Lt[i]=;
while(i-Lt[i]>=&&i+Lt[i]<=n&&A[i-Lt[i]]==A[i+Lt[i]]) ++Lt[i];
if(Lt[i]+i->mx) mx=Lt[i]+i-,pos=i;
if(i&) {if(Lt[i]>)ans=max(ans,Solve(i-Lt[i],i+Lt[i]-)+Lt[i]/*);}
else ans=max(ans,Solve(i-Lt[i],i+Lt[i]-)+(Lt[i]-)/*+);
ans=max(ans,(Lt[i]-(i%==))/*+(i%==));
}
mx=n+;pos=n+;
for(rint i=n;i;--i)
{
if(i>=mx) Rt[i]=min(i-mx+,Rt[*pos-i]);
else Rt[i]=;
while(i-Rt[i]>=&&i+Rt[i]<=n&&B[i-Rt[i]]==B[i+Rt[i]]) ++Rt[i];
if(i-Rt[i]+<mx) mx=i-Rt[i]+,pos=i;
if(i&){ if(Rt[i]>) ans=max(ans,Solve(i-Rt[i]+,i+Rt[i])+Rt[i]/*);}
else ans=max(ans,Solve(i-Rt[i]+,i+Rt[i])+(Rt[i]-)/*+);
ans=max(ans,(Rt[i]-(i%==))/*+(i%==));
}
for(rint x=;x<=n;++x)
if((!(x&))&&A[x]==B[x]) ans=max(ans,Solve(x-,x+)+);
printf("%d",ans);
return ;
}

[bzoj4755][Jsoi2016]扭动的回文串的更多相关文章

  1. BZOJ4755: [JSOI2016]扭动的回文串——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4755 JYY有两个长度均为N的字符串A和B. 一个“扭动字符串S(i,j,k)由A中的第i个字符到 ...

  2. BZOJ4755 JSOI2016扭动的回文串(二分答案+哈希)

    显然答案应该是由单串以某位置为中心的极长回文串继续在另一个串里拓展得到的.枚举中间位置二分答案,哈希判断即可.注意考虑清楚怎么处理偶回文,比如像manacher一样加分隔符. #include< ...

  3. BZOJ4755 [JSOI2016]扭动的回文串 【后缀数组】【manacher】

    题目分析: 我写了史上最丑的后缀数组,怎么办? 首先manacher一遍两个串,这样只用考虑第三问.用$作为间隔符拼接两个串,把第一个串翻转.枚举回文中心,取最长的回文串,对于剩下的部分利用LCP匹配 ...

  4. [BZOJ4755][JSOI2016]扭动的回文串(manacher+Hash)

    前两种情况显然直接manacher,对于第三种,枚举回文中心,二分回文半径,哈希判断即可. #include<cstdio> #include<algorithm> #defi ...

  5. 【BZOJ4755】 [Jsoi2016]扭动的回文串

    BZOJ4755 [Jsoi2016]扭动的回文串 Solution 考虑对于他给出的 A中的一个回文串: B中的一个回文串: 或者某一个回文的扭动字符串S(i,j,k) 这样子几个限制,我们1,2就 ...

  6. 【BZOJ4755】扭动的回文串(Manacher,哈希)

    [BZOJ4755]扭动的回文串(Manacher,哈希) 题面 BZOJ 题解 不要真的以为看见了回文串就是\(PAM,Manacher\)一类就可以过. 这题显然不行啊. 我们主要考虑如何解决跨串 ...

  7. [BZOJ]4755: [Jsoi2016]扭动的回文串

    Time Limit: 10 Sec  Memory Limit: 512 MB Description JYY有两个长度均为N的字符串A和B. 一个"扭动字符串S(i,j,k)由A中的第i ...

  8. 【题解】Luogu P4324 [JSOI2016]扭动的回文串

    原题传送门 这题实际挺水的 先对两个字符串分别跑马拉车 就能求出1.2类扭动回文串最大的长度 考虑第三类的扭动回文串\(S(i,j,k)\),一定可以表示为\(A(i,l)+A(l+1,j)+B(j, ...

  9. [JSOI2016]扭动的回文串

    题目 非常板子了 看到求什么最长的回文,我们就想到枚举回文中心的方法 首先对于这个回文串只包含在一个串内的情况,我们随便一搞就可以了,大概\(Manacher\)一下就没有了 对于那种扭动的回文串,我 ...

随机推荐

  1. JS 转换数据类型

    JavaScript 是一种动态数据类型语言,变量是没有类型的,可以随机赋予任意值,若变量要转换数据类型,有两种办法:隐式转换和显式转换. 隐式转换可转换为字符串(将一个值加上字符串) 数字(在值的前 ...

  2. slf4j 与 log4j2 基本用法

    简单的说 log4j2 是log4j2的升级版,解决了部分性能问题和部分死锁问题,其使用方式与使用配置与log4j相同. 建议使用maven依赖直接使用log4j2 <dependency> ...

  3. EasyUI 中datagrid 分页。

    注释:datagrid分页搞了好几天才完全搞好,网上没完全的资料.明天晚上贴代码. 睡觉.

  4. C# 后台构造json数据

    前后台传值一般情况下,都会用到json类型的数据,比较常见,但是每次用到的时候去网上找比较麻烦,所以自己记录一下,下次直接用. 构造的json串格式,如下: [{","name&q ...

  5. Apache Flink 分布式执行

    Flink 的分布式执行过程包含两个重要的角色,master 和 worker,参与 Flink 程序执行的有多个进程,包括 Job Manager,Task Manager 以及 Job Clien ...

  6. 竞赛基础篇---部分和问题(DFS)

    问题链接:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=1058 描述 给定整数a1.a2........an,判断是否可以从中选出若干数,使 ...

  7. scrapy选择器主要用法

    # 命令行输入:scrapy shell +链接,会自动请求url,得到的相应默认为response,开启命令行交互模式 scrapy shell http://doc.scrapy.org/en/l ...

  8. [转]pycharm常用快捷键及设置

    PyCharm3.0默认快捷键(翻译的) PyCharm Default Keymap 1.编辑(Editing) Ctrl + Space    基本的代码完成(类.方法.属性)Ctrl + Alt ...

  9. Python求解啤酒问题(携程2016笔试题)

    问题描述:一位酒商共有5桶葡萄酒和1桶啤酒,6个桶的容量分别为30升.32升.36升.38升.40升和62升,并且只卖整桶酒,不零卖.第一位顾客买走了2整桶葡萄酒,第二位顾客买走的葡萄酒是第一位顾客的 ...

  10. Java 并发编程:Callable和Future

    项目中经常有些任务需要异步(提交到线程池中)去执行,而主线程往往需要知道异步执行产生的结果,这时我们要怎么做呢?用runnable是无法实现的,我们需要用callable实现. import java ...