因为我很愚蠢所以用了很愚蠢的O(nlogn)的manacher+线段树做法

就是开两个线段树mn和mx分别表示左端点在i的最长回文子串和右端点在i的最长回文子串

用manacher求出每个点的最长回文子串,然后对于一组(i,f[i])(这里的i是加完#之后的串),我们考虑对原串贡献是对于中点右边一段回文串上点x的mn贡献i-2x+1,x最后加就变成在线段树上贡献i+1,然后同理对左边一段贡献2x-i+1,在线段树上贡献-i+1,注意这里要分一下奇偶还有仔细算一下边界

然后枚举断点,在线段树上查,取max即可

实际上注意到是可以O(n)的,mnmx更新时候的范围超过之后就变成负的没有意义了,所以直接更新区间端点,最后把i%2相同的向前/向后更新一下即可

或者直接用回文自动机预处理

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=200005;
int n,f[N],ans;
char c[N],s[N];
struct xds
{
int l,r,mx,lz;
}t[N<<2];
struct wk
{
xds t[N<<2];
void build(int ro,int l,int r)
{
t[ro].l=l,t[ro].r=r,t[ro].lz=t[ro].mx=-1e9;
if(l==r)
return;
int mid=(l+r)>>1;
build(ro<<1,l,mid);
build(ro<<1|1,mid+1,r);
}
void pd(int ro)
{
if(t[ro].lz!=-1e9)
{
t[ro<<1].mx=max(t[ro<<1].mx,t[ro].lz);
t[ro<<1].lz=max(t[ro<<1].lz,t[ro].lz);
t[ro<<1|1].mx=max(t[ro<<1|1].mx,t[ro].lz);
t[ro<<1|1].lz=max(t[ro<<1|1].lz,t[ro].lz);
t[ro].lz=-1e9;
}
}
void update(int ro,int l,int r,int v)
{//cerr<<l<<" "<<r<<endl;
if(l>r)
return;
if(t[ro].l==l&&t[ro].r==r)
{
t[ro].mx=max(t[ro].mx,v);
t[ro].lz=max(t[ro].lz,v);
return;
}
pd(ro);
int mid=(t[ro].l+t[ro].r)>>1;
if(r<=mid)
update(ro<<1,l,r,v);
else if(l>mid)
update(ro<<1|1,l,r,v);
else
update(ro<<1,l,mid,v),update(ro<<1|1,mid+1,r,v);
t[ro].mx=max(t[ro<<1].mx,t[ro<<1|1].mx);
}
int ques(int ro,int p)
{
if(t[ro].l==t[ro].r)
return t[ro].mx;
pd(ro);
int mid=(t[ro].l+t[ro].r)>>1;
if(p<=mid)
return ques(ro<<1,p);
else
return ques(ro<<1|1,p);
}
}mn,mx;
int main()
{
scanf("%s",c+1);
n=strlen(c+1);
for(int i=1;i<=n;i++)
s[2*i]=c[i],s[2*i+1]='#';
s[0]='$',s[1]='#',s[2*n+2]='%';
int mxw=0,w;
mn.build(1,1,n),mx.build(1,1,n);
for(int i=1;i<2*n+2;i++)
{
if(i<mxw)
f[i]=min(f[2*w-i],mxw-i);
else
f[i]=1;
for(;s[i+f[i]]==s[i-f[i]];f[i]++);
if(i+f[i]>mxw)
mxw=i+f[i],w=i;
if(s[i]=='#')
mx.update(1,max(1,(i+1)/2),min(n,(i+1)/2+(f[i]-1)/2-1),-i+1),mn.update(1,max(1,(i-1)/2-(f[i]-1)/2+1),min(n,(i-1)/2),i+1);
else
mx.update(1,max(1,i/2),min(n,i/2+f[i]/2-1),-i+1),mn.update(1,max(1,i/2-f[i]/2+1),min(n,i/2),i+1);
}
for(int i=2;i<=n;i++)
ans=max(ans,mx.ques(1,i-1)+2*(i-1)+mn.ques(1,i)-2*i);//,cerr<<i<<" "<<mn.ques(1,i)-2*i<<" "<<mx.ques(1,i)+2*i<<endl;;
printf("%d\n",ans);
return 0;
}

bzoj 2565: 最长双回文串【manacher+线段树】的更多相关文章

  1. BZOJ 2565: 最长双回文串 [Manacher]

    2565: 最长双回文串 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1842  Solved: 935[Submit][Status][Discu ...

  2. bzoj 2565: 最长双回文串 manacher算法

    2565: 最长双回文串 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem. ...

  3. 洛谷P4555 [国家集训队]最长双回文串(manacher 线段树)

    题意 题目链接 Sol 我的做法比较naive..首先manacher预处理出以每个位置为中心的回文串的长度.然后枚举一个中间位置,现在要考虑的就是能覆盖到i - 1的回文串中 中心最靠左的,和能覆盖 ...

  4. BZOJ 2565 最长双回文串(manacher)

    565: 最长双回文串 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3343  Solved: 1692[Submit][Status][Discu ...

  5. Manacher || P4555 [国家集训队]最长双回文串 || BZOJ 2565: 最长双回文串

    题面:P4555 [国家集训队]最长双回文串 题解:就.就考察马拉车的理解 在原始马拉车的基础上多维护个P[i].Q[i]数组,分别表示以i结尾最长回文子串的长度和以i开头的最长回文子串的长度 然后就 ...

  6. bzoj 2565: 最长双回文串

    Description 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为"abc",逆序为"cba",不相同).输入 ...

  7. bzoj 2565: 最长双回文串 回文自动机

    题目: Description 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为"abc",逆序为"cba",不相同 ...

  8. BZOJ 2565 最长双回文串(回文自动机)

    题意 给一个长度为N的字符串S.对于一个字符串AB,如果A和B都是回文串,那么称AB是一个双回文串.求问S最长双回文子串的长度?N <= 100000 题解 正反双向构造回文自动机,得到某一个点 ...

  9. HYSBZ 2565 最长双回文串 (回文树)

    2565: 最长双回文串 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1377  Solved: 714 [Submit][Status][Dis ...

随机推荐

  1. java验证码图片

    package com.su.servlet; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; impor ...

  2. WPF新手之如何将数据绑定到TreeView

    看过许多例子,全是绑定到类的,没人说如何绑定到某个对象,偏偏我这个绝对的新手就是要绑定到一个对象,只能自己摸索了: 首先要将数据绑定到容器,有以下几个默认条件:①元数据必须包装在List或者Obser ...

  3. python day-3 基本数据类型

    1. 编码 1. 最早的计算机编码是ASCII. 美国人创建的. 包含了英文字母(大写字母, 小写字母). 数字, 标点等特殊字符!@#$% 128个码位 2**7 在此基础上加了一位 2**8 8位 ...

  4. sanic官方文档解析之Custom Protocols(自定义协议)和Socket(网络套接字)

    1,Custom Protocol:自定义协议 温馨提示:自定义协议是一个高级用法,大多数的读者不需要用到此功能 通过特殊的自定义协议,你可以改变sanic的协议,自定义协议需要继承子类asyncio ...

  5. 关于chroot

    1 chroot做了什么 chroot只是修改了所有的path resolution过程,也就是说,chroot之后,所有的命令和库的根目录都是chroot到的目录. 2 chroot使用的条件 目标 ...

  6. CH 5102 Mobile Service(线性DP)

    CH 5102 Mobile Service \(solution:\) 这道题很容易想到DP,因为题目里已经说了要按顺序完成这些请求.所以我们可以线性DP,但是这一题的状态不是很好设,因为数据范围有 ...

  7. (27) java web的struts2框架的使用-基于表单的多文件上传

    和单个文件上传配置都是一样的,只是在action中接受参数时候,接受的是数组,不再是单个的文件. 一,action的实现: public class MutableFilesUpload extend ...

  8. 51nod 1600 Simple KMP

    又被机房神犇肉丝哥哥和glory踩爆了 首先这个答案的输出方式有点套路,当前的答案=上一个答案+每一个后缀的f值=上一个答案+上一次算的每个后缀的f值+当前每个后缀的深度 这个题意给了个根深度为-1有 ...

  9. HDU3613 Best Reward —— Manacher算法 / 扩展KMP + 枚举

    题目链接:https://vjudge.net/problem/HDU-3613 Best Reward Time Limit: 2000/1000 MS (Java/Others)    Memor ...

  10. Oracle:spool 的一个用法

    spool 是sqlplus的一个语法,非sql. 平时,我们通过ssh或者xmanger连接到oracle后,如果我们想把我们在上面操作的脚本及脚本执行过程.结果保存下来的话,可以通过spool来实 ...