题目分析:

我写了史上最丑的后缀数组,怎么办?

首先manacher一遍两个串,这样只用考虑第三问。用$作为间隔符拼接两个串,把第一个串翻转。枚举回文中心,取最长的回文串,对于剩下的部分利用LCP匹配即可。

代码:

 #include<bits/stdc++.h>
using namespace std; #define Sec first.second
#define Fir first.first const int maxn = ; int n,as,f[maxn],sa[maxn],height[maxn],h[maxn],rk[maxn*];
string s1,s2,vk;
int RMQ[maxn][]; void read(){cin >> n; cin >> s1 >> s2;}
int pf[maxn][]; void manacher(string &str){
vk.clear();
memset(f,,sizeof(f));
for(int i=;i<n;i++) vk.push_back(str[i]),vk.push_back('$');
f[] = ; int last = ,ct = ;
for(int i=;i<*n;i++){
f[i] = ;
if(i <= ct+last- && i+f[*ct-i]- <= ct+last-) f[i]=f[*ct-i];
while(i-f[i]>=&&i+f[i]<*n&&vk[i-f[i]]==vk[i+f[i]]){f[i]++;}
if(ct+last- < i+f[i]-) ct = i,last = f[i];
}
}
int X[maxn];
pair<pair<int,int>,int> pr[maxn];
vector <pair<int,int> > vec[maxn];
void get_sa(){
int z = s1.length();
for(int i=;i<z;i++) X[s1[i]]++;
for(int i=;i<=;i++)X[i] += X[i-];
for(int i=;i<z;i++) rk[i] = X[s1[i]];
for(int k=;(<<k)<=z;k++){
for(int i=;i<z;i++)
vec[rk[i+(<<k-)]].push_back(make_pair(rk[i],i));
//pr[i+1]=make_pair(make_pair(rk[i],rk[i+(1<<k-1)]),i);
//sort(pr+1,pr+z+1);
for(int i=,tms=;i<=z;i++)
for(int j=vec[i].size()-;j>=;j--){
pr[++tms]=make_pair(make_pair(vec[i][j].first,i),vec[i][j].second);
vec[i].pop_back();
}
for(int i=z;i>=;i--)
vec[pr[i].Fir].push_back(make_pair(pr[i].Sec,pr[i].second));
for(int i=,tms=;i<=z;i++)
for(int j=vec[i].size()-;j>=;j--){
pr[++tms] = make_pair(make_pair(i,vec[i][j].first),vec[i][j].second);
vec[i].pop_back();
}
int num = ;
for(int i=;i<=z;i++){
if(pr[i].first == pr[i-].first) rk[pr[i].second]=num;
else num++,rk[pr[i].second] = num;
}
}
for(int i=;i<z;i++) sa[rk[i]] = i;
}
void get_height(){
int z = s1.length();
for(int i=;i<z;i++){
if(i) h[i] = max(,h[i-]-); else h[i] = ;
if(rk[i]==) continue;
comp = sa[rk[i]-];
while(s1[comp+h[i]] == s1[i+h[i]])h[i]++;
}
for(int i=;i<z;i++) height[rk[i]] = h[i];
for(int i=;i<=z;i++) RMQ[i][] = height[i];
for(int k=;(<<k)<=z;k++){
for(int i=;i<=z;i++){
if(i+(<<k-)>z) RMQ[i][k] = RMQ[i][k-];
else RMQ[i][k] = min(RMQ[i][k-],RMQ[i+(<<k-)][k-]);
}
}
}
int getLCP(int L,int R){
if(L == R) return n-sa[L]; if(L > R) swap(L,R); L++;
int k = ; while((<<k+)<=R-L+)k++;
return min(RMQ[L][k],RMQ[R-(<<k)+][k]);
} void work(){
manacher(s1);
for(int i=;i<*n;i++) pf[i][] = f[i];
manacher(s2);
for(int i=;i<*n;i++) pf[i][] = f[i];
for(int i=;i<n/;i++) swap(s1[i],s1[s1.length()-i-]);
s1.push_back('$');
for(int i=;i<n;i++) s1.push_back(s2[i]);
get_sa(); get_height();
for(int i=;i<*n;i+=) {
if(pf[i][]%==)pf[i][]--;
int z = (i-pf[i][]+)/,w = (i+pf[i][]-)/;
int L = rk[n-z],R = rk[n+w+];
if(L > R) swap(L,R); int len = getLCP(L,R); as=max(as,w-z++len*);
if(pf[i][]%==)pf[i][]--;
z = (i-pf[i][]+)/,w = (i+pf[i][]-)/;
L = rk[n-z-],R = rk[n+w+];
if(L > R) swap(L,R); len = getLCP(L,R); as = max(as,w-z++len*);
}
for(int i=;i<*n;i+=) {
if(pf[i][]&) pf[i][]--;
int z = i-pf[i][]+,w = i+pf[i][]-;
if(pf[i][] == ){
int L = rk[n-(i-)/-],R = rk[n++(i-)/];
if(L > R) swap(L,R);int len=getLCP(L,R);as=max(as,len*);
} else{
z/=,w/=; int L = rk[n-z],R = rk[n++w];
if(L > R) swap(L,R);int len=getLCP(L,R);as=max(as,w-z++len*);
}
if(pf[i][]&) pf[i][]--;
z = i-pf[i][]+,w = i+pf[i][]-;
if(pf[i][] == ){
int L = rk[n-(i-)/-],R = rk[n++(i-)/];
if(L>R) swap(L,R); int len = getLCP(L,R); as = max(as,len*);
}else{
z/=,w/=; int L = rk[n-z-],R = rk[n+w+];
if(L > R) swap(L,R);int len=getLCP(L,R);as=max(as,w-z++len*); }
}
printf("%d",as);
} int main(){
//freopen("2.in","r",stdin);
read();
work();
return ;
}

BZOJ4755 [JSOI2016]扭动的回文串 【后缀数组】【manacher】的更多相关文章

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

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

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

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

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

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

  4. [bzoj3676]回文串[后缀数组+Manacher]

    后缀数组+Manacher #include <iostream> #include <cstdio> #include <cstdlib> #include &l ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Linq to XML操作XML文件

    LINQ的类型 在MSDN官方文件中,LINQ分为几种类型: . LINQ to Objects(或称LINQ to Collection),这是LINQ的基本功能,针对集合对象进行查询处理,包括基本 ...

  2. python数据类型--set(集合)

    博客地址:http://www.cnblogs.com/yudanqu/ 首先,简单介绍一下set,set就是我们中学时所学的集合,当时集合的性质就包括一点,集合里不能有重复的数字.我们现在所用到的集 ...

  3. python 链接 redis 失败 由于目标计算机积极拒绝,无法连接

    whereis redis-cli ps -ef |grep redis 1.启动redis redis-server & 2.查看redis 进程 ps -ef |grep redis 3. ...

  4. 11076: 小P的集合 位运算

    考虑当只有一个数出现奇数次的时候,我们可以很轻松的知道,把所有的数异或和即可,因为异或运算有一个非常有意思的性质,a^b^a=b 考虑当有两个数(a,b)出现奇数次的时候,我们异或和得到,num=a^ ...

  5. Gym 101873F Plug It In(二分图匹配)

    题目链接:http://codeforces.com/gym/101873/problem/F 题意:有n个插孔,m个机器,和一个插板,一个插孔可以连接一个机器,插板可以使一个插孔连接三个机器,找到最 ...

  6. python实现一个二分查找

    二分查找: 二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法.但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列 查找过程: 首先,假设表中元素是 ...

  7. asp.net mvc导出execl_转载

    public FileResult ExportExcel() { var sbHtml = new StringBuilder(); sbHtml.Append("<table bo ...

  8. html问题汇总

    1.textarea换行 textarea中无法使用<br/>换行,需要使用\n 2.textarea无法提交 我们知道表单中的元素需要设置name属性才能够提交,但是如果设置了disab ...

  9. 基于redis实现的点赞功能设计思路详解

    点赞其实是一个很有意思的功能.基本的设计思路有大致两种, 一种自然是用mysql等 数据库直接落地存储, 另外一种就是利用点赞的业务特征来扔到redis(或memcache)中, 然后离线刷回mysq ...

  10. scroll滚动条样式修改

    一般我们有两种情况会出现滚动条,一种是overflow,一种是使用scroll. 当我们需要改变这个滚动条样式的时候,我们需要做以下的修改: html: <div id="style- ...