【BZOJ】2342: [Shoi2011]双倍回文(Manacher)
2024-08-25 10:09:54
题目
传送门:QWQ
分析
(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 <bits/stdc++.h>
using namespace std;
const int maxn=;
char s2[maxn],s[ maxn];
int p[ maxn], len;
set<int> t;
void Manacher(){
len=strlen(s2+);
for(int i=;i<=len;i++){
s[i*-]='#'; s[i*]=s2[i];
}
s[len=len*+]='#';
int right=, pos=;
for(int i=;i<=len;i++){
if(i<right){ p[i]=min(p[*pos-i],right-i); } else p[i]=;
while(i+p[i]<=len &&i-p[i]> && 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+);
Manacher();
for(int i=;i<=n;i++) q[i]=i, f[i]=(p[i*+]-)/;
sort(q+,q++n,cmp);
int now=,ans=;
for(int i=;i<=n;i++){
while(now<=n&&q[now]-f[q[now]]<=i) {
t.insert(q[now]);
now++;
}
set<int>::iterator tmp=t.upper_bound(i+f[i]/);
if(tmp!=t.begin ()){
ans=max(ans,(*--tmp - i));
}
}
printf("%d\n",ans*);
return ;
}
/*
17
qwertyuaabbaabbaa
*/
最新文章
- 配置1000条ACE的脚本
- 使用log4net连接Mysql数据库配置
- RTC框架
- linux打包压缩命令汇总
- UVA 11374 Airport Express(最短路)
- IE8不显示字体图标
- 【Spark学习】Apache Spark项目简介
- 分解机(Factorization Machines)推荐算法原理
- HTTPS协议开通,Apache服务器CSR签名申请
- 纯css3打造瀑布流布局
- table td中的内容过长,显示为固定长度,多余部分用省略号显示
- Java语法基础学习DayTwenty(反射机制续)
- Windows下 tensorboard出现ValueError:Invalid format string
- 搭建vue脚手架---vue-cli
- RSA加密算法详解(二)
- 在kubernetes中运行单节点有状态MySQL应用
- C++中string类
- 用 select 语句实现递归的方法
- Sass预定义一些常用的样式
- spring cloud学习(五)断路器 Hystrix
热门文章
- c++多线程编程:实现标准库accumulate函数的并行计算版本
- GitLab+Rancher实践DevOps【转载】
- 程序设计入门-C语言基础知识-翁恺-第五周:函数-详细笔记(五)
- mysql安装优化
- Cannot setup mail box on Android
- apply函数应用
- Linux常用命令 (转载自大牛笔记 --- http://www.weixuehao.com)
- PCA最小平方误差理论推导
- BZOJ2342 Shoi2011 双倍回文 【Manacher】
- Codeforces 25E Test 【Hash】