[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. 树链剖分数据结构板题 题目大意:我 ...
随机推荐
- flutter 环境搭配 (一)
首先下载flutter SDK Flutter中文网 官网 (p2hp.com 选择下载 SDK 解压后 ,添加到环境变量中. 配置国内镜像, PUB_HOSTED_URL=https://pub.f ...
- 接口签名规则及Java代码demo实现
接口签名规则及Java代码demo实现 签名规则 签名生成的通用步骤如下: 第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用UR ...
- emlog新浪上传插件+接口 V1.1
Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` emlog新浪上传插件+接口 V1.1 日期:2018-4 ...
- 深入了解 C# Span:高性能内存操作的利器
深入了解 C# Span:高性能内存操作的利器 在 C# 7.2 中引入的 Span<T> 类型为我们提供了一种高效且安全地对内存进行操作的方式.Span<T> 是一个轻量级的 ...
- WatchDog:一款.NET开源的实时应用监控系统
项目介绍 WatchDog是一个开源(MIT License).免费.针对ASP.Net Core Web应用程序和API的实时应用监控系统.开发者可以实时记录和查看他们的应用程序中的消息.事件.HT ...
- Nginx SSL证书更新及密码套件更新
一.域名更换证书 ssl证书一般包括证书文件crt.cer.pem.pfx和私钥文件key. CER.CRT.PEM 和 PFX 是不同的证书文件格式,它们之间存在一些区别: CER (DER 编码) ...
- Linux C 读写超过2G的大文件 注意事项
背景 在项目中做大文件的增量读写,遇到了问题: fopen : Value too large for defined data type. 习惯性地根据这个提示查阅的有关资料显示: 1)工具链太老了 ...
- Simple WPF: WPF 透明窗体和鼠标事件穿透
一个自定义WPF窗体的解决方案,借鉴了吕毅老师的WPF制作高性能的透明背景的异形窗口一文,并在此基础上增加了鼠标穿透的功能.可以使得透明窗体的鼠标事件穿透到下层,在下层窗体中响应. 这个方法不一定是制 ...
- Power BI进阶秘籍,干货满满!如何将度量值转化为切片器(动态切换分析指标),实操指南来了!
Power BI进阶秘籍,干货满满!如何将度量值转化为切片器(动态切换分析指标),实操指南来了! 想要在Power BI中让度量值也能像维度一样灵活筛选?没问题,这里就为你揭秘如何将度量值转化为切 ...
- 一文搞懂到底什么是 AQS
前言 日常开发中,我们经常使用锁或者其他同步器来控制并发,那么它们的基础框架是什么呢?如何实现的同步功能呢?本文将详细讲解构建锁和同步器的基础框架--AQS,并根据源码分析其原理. 一.什么是 AQS ...