博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【BZOJ】2342: [Shoi2011]双倍回文(Manacher)
阅读量:4314 次
发布时间:2019-06-06

本文共 1302 字,大约阅读时间需要 4 分钟。

题目

 

 

分析

(sb如我写了发不知道什么东西在洛谷上竟然水了84分

嗯咳

设$ i $为双重回文的中心

如果$ j~i $ 可以被算作答案,只有满足如下两式:

  • $ p[j]+j \geq i $
  • $ 2*(i-j) \leq p[j] $

计算时我们先做一次马拉车,然后按照 $ p[j]+j \geq i $排序,保证它的单调,接着把满足$ 2*(i-j) \leq p[j] $扔进set里询问。

 

代码

#include 
using namespace std;const int maxn=1050000;char s2[maxn],s[ maxn];int p[ maxn], len;set
t;void Manacher(){ len=strlen(s2+1); for(int i=1;i<=len;i++){ s[i*2-1]='#'; s[i*2]=s2[i]; } s[len=len*2+1]='#'; int right=0, pos=0; for(int i=1;i<=len;i++){ if(i
0 && s[i+p[i]]==s[i-p[i]]) p[i]++; if(i+p[i]>right){ right=i+p[i]; pos=i; } }}int q[maxn], f[maxn];bool cmp(int a,int b){ return (a-f[a])<(b-f[b]); }int main(){ int n; scanf("%d%s",&n,s2+1); Manacher(); for(int i=1;i<=n;i++) q[i]=i, f[i]=(p[i*2+1]-1)/2; sort(q+1,q+1+n,cmp); int now=1,ans=0; for(int i=1;i<=n;i++){ while(now<=n&&q[now]-f[q[now]]<=i) { t.insert(q[now]); now++; } set
::iterator tmp=t.upper_bound(i+f[i]/2); if(tmp!=t.begin ()){ ans=max(ans,(*--tmp - i)); } } printf("%d\n",ans*4); return 0;}/*17qwertyuaabbaabbaa*/

 

 

 

转载于:https://www.cnblogs.com/noblex/p/9191804.html

你可能感兴趣的文章
200道物理学难题——001 三只蜗牛
查看>>
构建App首页
查看>>
BZOJ1443: [JSOI2009]游戏Game
查看>>
zookeeper客户端Watcher管理
查看>>
第二代蜂窝移动通信系统概述
查看>>
[转载] IOS 自动布局--先进的自动布局工具箱
查看>>
Matrix的一些知识
查看>>
sqlserver数据库中没有维护计划,使用windows默认的计划任务实现数据备份
查看>>
python __future__ 使用
查看>>
OpenGL4.6+vs2017+CMake+Glad+Glfw-3.2.1+GLM随手记一发完整版OpenGL配置过程
查看>>
第15周个人进度条
查看>>
Vue学习笔记:methods、computed、watch的区别
查看>>
朴素贝叶斯新闻分类,新浪SAE碰到的问题
查看>>
day19 Python super()
查看>>
JavaEE
查看>>
【BZOJ 4059】 (分治暴力|扫描线+线段树)
查看>>
反编译Silverlight项目
查看>>
BZOJ 1066 蜥蜴(网络流)
查看>>
提高批量插入数据的方法
查看>>
Linux重启Mysql命令
查看>>