首页 > 其他分享 >[POI2012] PRE-Prefixuffix 题解

[POI2012] PRE-Prefixuffix 题解

时间:2024-07-24 16:07:56浏览次数:16  
标签:PRE POI2012 题解 texttt int Big res border mod

前言

题目链接:洛谷

题意简述

给出长为 \(n\) 的串 \(\texttt{S}\)。求最大的 \(l\) 满足:

\[2l \leq n \land \texttt{S}[1 \ldots l] \doteq \texttt{S}[n - l + 1 \ldots n] \]

其中 \(\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;
}

标签:PRE,POI2012,题解,texttt,int,Big,res,border,mod
From: https://www.cnblogs.com/XuYueming/p/18320957

相关文章

  • 题解:2024牛客多校第三场 B
    BCrashTestheader时间限制:C/C++2秒,其他语言4秒空间限制:C/C++1048576K,其他语言2097152K64bitIOFormat:%lld题目描述Afterfiveyears,themosthigh-profileeventinmotorracing,Formula1,returnstoChina.TheChineseGrandPrixwasrecentlyheldatthe......
  • object dict cannot be used in await expression报错解释
    报错解释:这个错误通常出现在使用Python的异步编程模型时,尝试在一个不支持异步的对象上使用await关键字。在Python中,await关键字只能在异步函数中使用,而异步函数通常定义在asyncdef语句中。错误"objectdictcannotbeusedinawaitexpression"意味着你正尝试在一个普通的字典......
  • 题解:P10450 [USACO03MAR] Best Cow Fences G
    题目链接O(n^3)做法直接暴力枚举长度、起点,再全部跑一边求平均数。附上我丑陋的代码和提交记录,这个代码可以得42分。#include<bits/stdc++.h>usingnamespacestd;constintNR=1e5+5;longlongn,l,a[NR],sum,ave;intmain(){ cin>>n>>l; for(inti......
  • [CEOI2011] Matching 题解
    前言题目链接:洛谷。在上一题之后,模拟赛又放了一道KMP重定义相等的问题,但是寄了,故再记之。题意简述现在给出\(1\simn\)的排列\(p\)和序列\(h_1,h_2,\cdots,h_m\)​​,请你求出哪些\(h\)的子串符合排列\(p\)。串\(a_i\)符合一个排列被定义为其从小到大排序后得......
  • ABC250H 题解
    题面我们先考虑如何让连续的不在房子中的时间尽量短:我们考虑两个有房子的点\(x,y\),如果\(x\rightsquigarrowu\xrightarrow{w}v\rightsquigarrowy\)这条路径上除了\(x,y\)不存在有房子的点,那么我们可以找到这样一条路径,一定不劣:令\(a,b\)分别为最靠近\(u,v\)的有房......
  • 论文阅读:Enhancing Chinese Character Representation With Lattice-Aligned Attentio
    方法:格对齐注意力网络(LAN)旨在对词-字符格结构上的密集交互进行建模,以增强字符表示。首先,应用软词典特征策略构建词-字符格结构,然后得到了字符和词序列的固定维度表示。接着,利用格对齐注意力来显示地模拟不同特征空间之间的密集交互。最后,应用条件随机场(CRF)和关系分类器来执......
  • CF547D Mike and Fish 题解
    Description给定\(n\)个整点。你要给每个点染成红色或蓝色。要求同一水平线或垂直线上两种颜色的数量最多相差\(1\)。\(n,x_i,y_i\le2\times10^5\)。Solution考虑给每条水平线和垂直线建一个点,对于每个整点就把它对应的两条线连一条边。题目就转化为了给每条边定......
  • 配置文件mybatis-plus: global-config: db-config: table-prefix: true
    具体来说,table-underline的含义是:当table-underline设置为true时:假设你有一个实体类名为UserInfo,那么MyBatis-Plus会默认去数据库中寻找名为user_info的表(即,驼峰命名法自动转换为下划线命名法)。同理,如果你的数据库表名是user_info,但你的实体类名是UserInfo,那么M......
  • 界面控件开发包DevExpress v24.1.4全新发布
    DevExpress Universal拥有.NET开发需要的所有平台控件,包含600多个UI控件、报表平台、DevExpressDashboardeXpressApp框架、适用于VisualStudio的CodeRush等一系列辅助工具。屡获大奖的软件开发平台DevExpress近期重要版本v24.1已正式发布,该版本拥有众多新产品和数十个具有......
  • ARC117F Gateau 题解
    ARC117FGateau题解题解区好像都没有对dp详细解释,本文将稍细致地说一说dp部分。题目大意给定一个长度为\(2N\)的环,环上每个节点有属性值\(B_i\(i=0,\dots,2N-1)\)和\(2N\)个限制,第\(i\)个限制形如\(\sum\limits_{j=i}^{i+N-1}B_j\geqA_i\),向环上的节点赋值,使得......