[POI2012] PRE-Prefixuffix 题解
前言
题目链接:洛谷。
题意简述
给出长为 \(n\) 的串 \(\texttt{S}\)。求最大的 \(l\) 满足:
\]
其中 \(\doteq\) 表示循环相同。
题目分析
看到循环相同,套路化想到,两个字符串一定可以表示成 \(\texttt{AB}\) 和 \(\texttt{BA}\) 的形式。那么 \(\texttt{S}\) 就能表示成 \(\texttt{ABTBA}\)。那么可以枚举两侧的 \(\texttt{A}\),接下来问题变成了求 \(\texttt{S}\) 扣掉两侧的 border。
求 border,想到每次线性跑一遍 KMP,但是这样是 \(\Theta(n^2)\),能够得到 \(50 \%\) 的部分分。考虑优化。
发现 \(i \sim n - i + 1\) 的 border 和 \(i - 1 \sim n - i\) 的 border 在某些情况下有很大一部分是重合的。进一步发现,从前者到后者,border 最多增加 \(2\),如图。

淡蓝色的是 \(i \sim n - i + 1\) 的 border,\(i - 1 \sim n - i\) 的 border 在此基础上多了红色和绿色部分。
所以考虑递推。记 \(f_i\) 表示 \(\texttt{S}\) 删去前 \(i\) 个和后 \(i\) 个字符的 border。边界 \(f_{\Big \lfloor \cfrac{n}{2} \Big \rfloor + 1} = 0\)。每次 \(f_i\) 初始值设置成 \(f_{i + 1} + 2\),当然需要和 \(\Big \lfloor \cfrac{n}{2} \Big \rfloor - i\) 取个 \(\min\)。然后一直让 \(f_i \gets f_i - 1\),直到满足找到一个长为 \(f_i\) 的 border,这样显然是最优的。
至于判断是否为 border,使用哈希即可。
时间复杂度的话,把 \(f\) 看成不断 \(+2\) 和 \(-1\),前者次数不会超过 \(\Big \lfloor \cfrac{n}{2} \Big \rfloor\),所以是 \(\Theta(n)\) 的。
代码
// #pragma GCC optimize(3)
// #pragma GCC optimize("Ofast", "inline", "-ffast-math")
// #pragma GCC target("avx", "sse2", "sse3", "sse4", "mmx")
#include <iostream>
#include <cstdio>
#define debug(a) cerr << "Line: " << __LINE__ << " " << #a << endl
#define print(a) cerr << #a << "=" << (a) << endl
#define file(a) freopen(#a".in", "r", stdin), freopen(#a".out", "w", stdout)
#define main Main(); signed main() { return ios::sync_with_stdio(0), cin.tie(0), Main(); } signed Main
using namespace std;
const int mod = 1314736520;
const int bas = 131;
inline int add(int a, int b) {
return a + b >= mod ? a + b - mod : a + b;
}
inline int sub(int a, int b) {
return a - b < 0 ? a - b + mod : a - b;
}
inline int mul(int a, int b) {
return 1ll * a * b % mod;
}
int n, hsh[1000010], pw[1000010];
char str[1000010];
int f[1000010], ans;
inline int gethash(int l, int r) {
return l > r ? 0 : sub(hsh[r], mul(hsh[l - 1], pw[r - l + 1]));
}
signed main() {
scanf("%d%s", &n, str + 1), pw[0] = 1;
for (int i = 1; i <= n; ++i) {
hsh[i] = add(mul(hsh[i - 1], bas), str[i]);
pw[i] = mul(pw[i - 1], bas);
}
for (int i = n / 2; i >= 1; --i) {
int res = min(f[i + 1] + 2, n / 2 - i);
while (res >= 1 && gethash(i + 1, i + res) != gethash(n - i - res + 1, n - i))
--res;
f[i] = res;
}
for (int i = 1; i <= n / 2; ++i)
if (gethash(1, i) == gethash(n - i + 1, n))
ans = max(ans, i + f[i]);
printf("%d\n", ans);
return 0;
}
[POI2012] PRE-Prefixuffix 题解的更多相关文章
- POI2012题解
POI2012题解 这次的完整的\(17\)道题哟. [BZOJ2788][Poi2012]Festival 很显然可以差分约束建图.这里问的是变量最多有多少种不同的取值. 我们知道,在同一个强连通分 ...
- 【BZOJ2803】[Poi2012]Prefixuffix 结论题
[BZOJ2803][Poi2012]Prefixuffix Description 对于两个串S1.S2,如果能够将S1的一个后缀移动到开头后变成S2,就称S1和S2循环相同.例如串ababba和串 ...
- [BZOJ2803][Poi2012]Prefixuffix
2803: [Poi2012]Prefixuffix Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 219 Solved: 95[Submit][St ...
- bzoj 2803 [Poi2012]Prefixuffix 兼字符串hash入门
打cf的时候遇到的问题,clairs告诉我这是POI2012 的原题..原谅我菜没写过..于是拐过来写这道题并且学了下string hash. 字符串hash基于Rabin-Karp算法,并且对于 ...
- [Poi2012]Festival 题解
[Poi2012]Festival 时间限制: 1 Sec 内存限制: 64 MB 题目描述 有n个正整数X1,X2,...,Xn,再给出m1+m2个限制条件,限制分为两类: 1. 给出a,b (1 ...
- 题解:POI2012 Salaries
题解:POI2012 Salaries Description The Byteotian Software Corporation (BSC) has \(n\) employees. In BSC ...
- BZOJ2803[Poi2012]Prefixuffix——hash
题目描述 对于两个串S1.S2,如果能够将S1的一个后缀移动到开头后变成S2,就称S1和S2循环相同.例如串ababba和串abbaab是循环相同的.给出一个长度为n的串S,求满足下面条件的最大的L: ...
- 【题解】 [POI2012]FES-Festival (差分约束)
懒得复制题面,戳我戳我 Question: (因为网上找不到好的翻译,这里简单复述一下) 告诉你\(m1+m2\)个约束条件,然后要你找出\(X_1-X_n\)这些数字,求满足要求的数列中不同的数字个 ...
- bzoj 2803 [POI2012]prefixuffix hsh+性质
题目大意 bzoj 2803 对于两个串S1.S2,如果能够将S1的一个后缀移动到开头后变成S2,就称S1和S2循环相同.例如串ababba和串abbaab是循环相同的. 给出一个长度为n的串S,求满 ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
随机推荐
- 我所关注的几个spring设计模式
Spring框架中实现了许多的设计模式,而且都是非常优先的实现,这些值得我们学好好习. 不过话说回来,我觉得自己只要关注几个即可: 单例 工厂 代理 适配器 观察者 委派 在各种设计模式中,适配器和装 ...
- CLR via C# 笔记 -- 数组(16)
1. 数组隐式继承 System.Array,所以数组是引用类型.变量包含的是对数组的引用,而不是包含数据本身的元素. 2. 数组协变性.将数组从一种类型转换为另一种类型. string[] sa = ...
- libevent之evbuffer
目录 Evbuffers:缓冲 IO 的实用程序功能 简介 创建或释放 evbuffer Evbuffers 和线程安全 检查 evbuffer 向 evbuffer 添加数据:基础知识 将数据从一个 ...
- ETL服务器连接GaussDB(DWS)集群客户端配置
问题描述:给ETL的服务器上安装gsql的工具,用来连接GaussDB(DWS)集群,做数据抽取用 DWS:GaussDB(DWS) 8.2.1-ESL 1.获取软件包 登录FusionInsight ...
- 使用kk在centos7上离线部署kubesphere v3.0.0详解
环境准备 以三台centos 7.7 64bit 为例: 确保所有机器已经安装所需依赖软件(sudo curl openssl ebtables socat ipset conntrack docke ...
- 详细讲解 Keil Pack Installer,以及通过 Keil 官网获取 Pack
前言 大家好,我是梁国庆. 收到粉丝留言,说 Keil 安装 Pack 不太明白,可不可以详细演示一下? 当然可以有,直接视频+文章全部安排,我就是宠粉. PS:第一次录视频有些紧张,见谅哈. 微信视 ...
- 3.8折年终钜惠,RK3568J国产工业评估板
3.8折年终钜惠,RK3568J国产工业评估板活动火热进行中,错过等一年! -核心板国产化率100%,提供报告-瑞芯微四核ARM Cortex-A55@1.8GHz-4K视频解码.1080P视频编码. ...
- AIGC的行业发展
1. AIGC的行业发展 AIGC(Artificial Intelligence Generated Content,人工智能生成内容)是利用人工智能技术来自动生成内容的一种新型内容创作方式.它基于 ...
- Docker 总体架构图解
Docker 的总体架构 Docker 是一个 C/S 模式的架构,后端是一个松耦合架构,模块各司其职. 下图是它的总体架构图: 1. 用户使用 Docker Client 与 Docker Daem ...
- git使用教程及常用命令
1.初次本地git连接远程仓库,并提交代码到远程仓库 第一步 码云上创建仓库 第二步 在需要上传的项目处右键-->git bush here 第三步 初始化本地git库 git init 设定 ...