传送门

对\(A\)、\(B\)串各跑一遍\(manacher\),求出第\(1\)、\(2\)类扭动回文串的最大长度。

考虑第三类的扭动回文串\(S(i,j,k)\),一定可以表示为\(A(i,l)+A(l+1,j)+B(j,k)\)或\(A(i,j)+B(j,l)+B(l+1,k)\),其中,第一段与第三段对称(第一段正着\(Hash\)和第三段反着\(Hash\)相同),第二段是一个回文子串,三段都可以是空串。

我们可以分别在\(AB\)上枚举对称中心,然后感性理解一下发现肯定是取以该对称中心为中心的最长回文串作为中间那段是最优的。然后对于第一段和第三段分别二分其长度就好了

//minamoto
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
inline char gc(){char ch;while((ch=getc())<'A'||ch>'Z');return ch;}
const int N=2e5+5,P1=1e9+7,P2=998244353;
int a[N],b[N],sum[N][2],num[N][2],bin[N][2],f[N],g[N];
int n,m,ans,p,l,r;char ch;
bool ck(int l1,int r1,int l2,int r2){
int x,y;
x=(sum[r1][0]-1ll*sum[l1-1][0]*bin[r1-l1+1][0]%P1)%P1;
y=(num[l2][0]-1ll*num[r2+1][0]*bin[r2-l2+1][0]%P1)%P1;
x=(x+P1)%P1,y=(y+P1)%P1;if(x!=y)return false;
x=(sum[r1][1]-1ll*sum[l1-1][1]*bin[r1-l1+1][1]%P2)%P2;
y=(num[l2][1]-1ll*num[r2+1][1]*bin[r2-l2+1][1]%P2)%P2;
x=(x+P2)%P2,y=(y+P2)%P2;return x==y;
}
int calc(int j,int k){
int l=0,r=min(j,n-k+1),res=0;
while(l<=r){
int mid=(l+r)>>1;
if(ck(j-mid+1,j,k,k+mid-1))res=mid,l=mid+1;else r=mid-1;
}return res;
}
int main(){
// freopen("testdata.in","r",stdin);
scanf("%d",&n);bin[0][0]=bin[0][1]=1;fp(i,1,n)bin[i][0]=1ll*bin[i-1][0]*27%P1,bin[i][1]=1ll*bin[i-1][1]*27%P2;
a[0]=b[0]=0,a[n*2+2]=b[n*2+2]=28,a[1]=b[1]=27;
fp(i,1,n)ch=gc(),a[i*2]=ch-'A'+1,a[i*2+1]=27;
fp(i,1,n)ch=gc(),b[i*2]=ch-'A'+1,b[i*2+1]=27;
p=0;fp(i,2,n*2){
if(i<=p+f[p])f[i]=min(f[2*p-i],p+f[p]-i);
while(a[i-f[i]-1]==a[i+f[i]+1])++f[i];
if(i+f[i]>p+f[p])p=i;
}p=0;fp(i,2,n*2){
if(i<=p+g[p])g[i]=min(g[2*p-i],p+g[p]-i);
while(b[i-g[i]-1]==b[i+g[i]+1])++g[i];
if(i+g[i]>p+g[p])p=i;
}fp(i,2,n*2)cmax(ans,max(f[i],g[i]));
fp(i,1,n){
sum[i][0]=(1ll*sum[i-1][0]*27%P1+a[i*2])%P1;
sum[i][1]=(1ll*sum[i-1][1]*27%P2+a[i*2])%P2;
}fd(i,n,1){
num[i][0]=(1ll*num[i+1][0]*27%P1+b[i*2])%P1;
num[i][1]=(1ll*num[i+1][1]*27%P2+b[i*2])%P2;
}fp(i,2,n*2){
l=(i-f[i]+1)>>1,r=(i+f[i])>>1;
cmax(ans,f[i]+calc(l-1,r)*2);
l=(i-g[i]+1)>>1,r=(i+g[i])>>1;
cmax(ans,g[i]+calc(l,r+1)*2);
}printf("%d\n",ans);return 0;
}

P4324 [JSOI2016]扭动的回文串的更多相关文章

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

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

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

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

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

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

  4. [bzoj4755][Jsoi2016]扭动的回文串

    来自FallDream的博客,未经允许,请勿转载,谢谢. JYY有两个长度均为N的字符串A和B. 一个“扭动字符串S(i,j,k)由A中的第i个字符到第j个字符组成的子串与B中的第j个字符到第k个字符 ...

  5. [JSOI2016]扭动的回文串

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

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

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

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

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

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

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

  9. BZOJ4755:[JSOI2016]扭动的回文串

    浅谈\(Manacher\):https://www.cnblogs.com/AKMer/p/10431603.html 题目传送门:https://lydsy.com/JudgeOnline/pro ...

随机推荐

  1. 前端学习之--html

    html 文件就是充当模板使用,包含head头和body身体,body包含众多的标签,每个标签都使用尖括号包裹,内部由标签名和标签属性构成.其中标签分为2类: 1:块级标签,特点:占用一行,如:< ...

  2. 洛谷——P2916 [USACO08NOV]为母牛欢呼Cheering up the Cows

    https://www.luogu.org/problem/show?pid=2916 题目描述 Farmer John has grown so lazy that he no longer wan ...

  3. 51nod 1907(多项式乘法启发式合并)

    题目: 分析: 对于一个确定的生成子图,很明显是在一个连通块上走,走完了再跳到另一个连通块上,假设连通块个数为cnt,那么答案一定是$min(a_{cnt-1},a_cnt,..,a_{n-1})$ ...

  4. 七天从零基础学习android(1)--配置环境

    在写这篇文的时候android开发经验还是0,是一个萌新,这是一篇记录一个萌新从零android编程基础到能编写一个记账本的开发过程(至少我是这样美好的希望着的) 首先因为是没有开发基础的,直接上百度 ...

  5. sql 2005 安装

    http://blog.csdn.net/wochuailimin/article/details/6120462 http://www.cnblogs.com/huangcong/archive/2 ...

  6. Java中常见的排序算法

    这是我摘取的一段英文资料.我认为学习算法之前,对各种排序得有个大致的了解: Sorting algorithms are an important part of managing data. At ...

  7. angular react vue 浏览器兼容情况汇总

    一.逻辑层 框架 (1)angular Angular早在1.3版本就抛弃了对ie8的支持. (2)react React 早在0.14.x 版本就抛弃了对ie8的支持. (3)vue Vue就没打算 ...

  8. ubuntu下安装pycharm的方法

    linux下安装pycharm是比较麻烦的. 安装pycharm之前要安装好JDK8,依次执行如下的命令: sudo add-apt-repository ppa:webupd8team/java s ...

  9. CSS制作翻牌特效

    应一个朋友要求替他把原本静态页面做成翻牌的特效. 主要应用了CSS3的transform,transiton.首先写好标签,一个ul下两个li元素,通过position的absolue设置两个li元素 ...

  10. udhcp源码详解(三) 下 之配置信息的读取

    上节讲解了read_config函数,读取配置信息到server_config的相应成员变量里,但read_config函数只负责把配置信息重文件里读出来,具体怎么把信息填写到指定的地址内,是调用ke ...