传送门

对\(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. [Bzoj4540][Hnoi2016] 序列(莫队 + ST表 + 单调队列)

    4540: [Hnoi2016]序列 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1567  Solved: 718[Submit][Status] ...

  2. Spring的AOP AspectJ切入点语法详解(转)

    一.Spring AOP支持的AspectJ切入点指示符 切入点指示符用来指示切入点表达式目的,在Spring AOP中目前只有执行方法这一个连接点,Spring AOP支持的AspectJ切入点指示 ...

  3. DELPHI7调用BERLIN中间件的中文字段名乱码的解决办法

    MSSQL数据库的表使用中文字段名,BERLIN开发的DATASNAP中间件,DELPHI7调用中间件的查询方法返回数据给CLIENTDATASET.DATA,发现中文字段名乱码,中文字段名的值可以正 ...

  4. poj 1695 Magazine Delivery 记忆化搜索

    dp[a][b][c],表示三个人从小到大依次在a,b.c位置时.距离结束最少的时间. 每次选一个人走到c+1位置搜索就好了. 坑点在于不能floyd.预计题目没说清楚.意思就是假设没送Li,那么Li ...

  5. [Angular] Write Compound Components with Angular’s ContentChild

    Allow the user to control the view of the toggle component. Break the toggle component up into multi ...

  6. Java注释中的@deprecated与源代码中的@Deprecated

    用 @Deprecated注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择.在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告. 其次,请注意标题, ...

  7. Hibernate也须要呵护——Hibernate的泛型DAO

    众所周之.面向对象的基础是抽象.也能够说,抽象促使编程在不断发展. 对于数据库的訪问,以前写过HqlHelper.EFHelper.编写Spring+Hibernate框架下的应用.也相同离不了编写一 ...

  8. OO模式-Composite

    组合模式也叫做"部分-总体"模式,这样事实上定义也就非常明显了,正好和数据结构的知识相相应.把对象组合成树形结构以表示"部分-总体"的层次结构. 先看类图: w ...

  9. 使用PowerShell 创建SharePoint 站点

    使用PowerShell 创建SharePoint 站点         在SharePoint开发中,你应该学会使用PowerShell管理SharePoint网站.SharePoint Manag ...

  10. C从控制台(stdin)输入带空格的字符串到字符数组中

    用scanf("%s",array); 的话遇到空格就停止接收后面的字符了,那怎么才能接收带空格的字符串呢? 1.用 gets() ,它可以接收带空格的字符串, 直到回车才结束输入 ...