[题解] Luogu P5446 [THUPC2018]绿绿和串串
[题解] Luogu P5446 [THUPC2018]绿绿和串串
·题目大意
- 定义一个翻转操作\(f(S_n)\),表示对于一个字符串\(S_n\),
有\(f(S)= \{S_1,S_2,...,S_{n-1},S_n,S_{n-1},...S_2,S_1 \}\)。 - 现在给定一个长度为\(n\)的字符串\(S^{'}\)表示原字符串\(S\)经过若干次(可能为0)旋转之后的一个前缀,
求原来字符串可能的长度\(l\)。 - 显然当\(l > n\)时一定可行,所以只需要输出所有的\(l\leq n\)即可。
\(|S|\leq 10^6,\Sigma |S| \leq 5 \times 10^6\)
·解题思路
首先想到用 \(Manacher\) 。
由于进行翻转操作后回文串长度必定为奇数,所以不用插入字符,然后考虑什么情况下长度是可行的。
- 我们定义一个 \(flag\) 数组,\(flag[i]\) 表示长度为 \(i\) 时是可行的。回文数组为\(p\),\(p[i]\)表示第 \(i\) 位的回文半径位 \(p[i]\)
- 如果只进行了一次翻转操作即可使得前缀为\(S^{'}\),那么有 \(i + p[i] - 1 == n\)
- 如果需要进行\(k\)次翻转才可以使得前缀为\(S^{'}\),那么有 \(i - p[i] + 1 == 1\),然后可以转化为进行\(k - 1\)次的情况。
但是实际操作中我们不用跑 \(k\) 次,只需要倒着跑并记录 \(flag\) ,因为当我们处理长度为 \(i\) 的时候,\(flag[i + 1]\) 到 \(flag[n]\) 都已经处理过了,所以判断 \(flag[i + p[i] - 1] == 1\)即可。 - 时间复杂度为\(O(n)\)。
代码实现
#include <iostream>
#include <cstring>
using namespace std;
#define reg register
namespace io {
char ch[20];
template<typename T>inline void write(T x) {
(x < 0) && (x =- x, putchar('-'));
(x) || putchar('0');
reg int i = 0;
while (x) ch[i++] = x % 10 ^48, x /= 10;
while (i) putchar(ch[--i]);
}
}//快写
#define wt io::write
const int maxN = 1000010;
char s[maxN];
int p[maxN], flag[maxN];
int n;
void work();
int main() {
int t;
scanf("%d", &t);
while (t--) work();
return 0;
}
void work() {
for (reg int i = 1; i <= n; ++i) flag[i] = p[i] = s[i] = 0;
n = 1; s[0] = '@';
scanf("%s", s + 1);
while (s[n]) ++n;
--n;
for (reg int i = 1, r = 0, mid = 0; i <= n; ++i) {
if (i <= r) p[i] = min(p[mid * 2 - i], r - i + 1);
while (s[i + p[i]] == s[i - p[i]]) ++p[i];
if (i + p[i] - 1 >= r) r = i + p[i] - 1, mid = i;
}//Manacher
for (reg int i = n; i; --i) {
if (i + p[i] - 1 == n || (flag[i + p[i] - 1] && i - p[i] + 1 == 1)) flag[i] = 1;
}//上面说的两种情况
for (reg int i = 1; i <= n; ++i)
if (flag[i]) wt(i), putchar(' ');
putchar('\n');
}
[题解] Luogu P5446 [THUPC2018]绿绿和串串的更多相关文章
- 【题解】P5446 [THUPC2018]绿绿和串串(manacher)
[题解]P5446 [THUPC2018]绿绿和串串(manacher) 考虑对于一个串进行\(f\)操作,就是让他变成一个以最后一个节点为回文中心的回文串. 那么对于某个位置\(p\),假如它是一个 ...
- LOJ#6387 「THUPC2018」绿绿与串串 / String (Manacher || hash+二分)
题目描述 绿绿和 Yazid 是好朋友.他们在一起做串串游戏. 我们定义翻转的操作:把一个串以最后一个字符作对称轴进行翻转复制.形式化地描述就是,如果他翻转的串为 RRR,那么他会将前 ∣R∣−1个字 ...
- 洛谷$P5446\ [THUPC2018]$绿绿和串串 $manacher$
正解:$manacher$ 解题报告: 传送门$QwQ$ 考虑这个操作的实质是啥$QwQ$?其实就,变成以最后一个节点为回文中心的回文子串嘛$QwQ$.显然就先跑个马拉车再说呗$QwQ$. 然后接着考 ...
- LOJ6387 [THUPC2018] 绿绿与串串 【manacher】
题目分析: 比较简单,先跑一边manacher,然后对于回文部分可以碰到末尾的一定满足条件,否则向后转移. 代码: #include<bits/stdc++.h> using namesp ...
- loj6387 「THUPC2018」绿绿与串串 / String
还是很好做的,大致就是manacher,每个位置为中心的最长回文串要是能抵到最右边就合法,要是能抵到最左边,那这个点的是否合法取决于以这个点为中心的最长回文串的右端点是否合法. #include &l ...
- 题解 Luogu P2499: [SDOI2012]象棋
关于这道题, 我们可以发现移动顺序不会改变答案, 具体来说, 我们有以下引理成立: 对于一个移动过程中的任意一个移动, 若其到达的位置上有一个棋子, 则该方案要么不能将所有棋子移动到最终位置, 要么可 ...
- 题解 luogu P1144 【最短路计数】
本蒟蒻也来发一次题解第一篇请见谅 这个题有几个要点 1.无向无权图,建图的时候别忘记建来回的有向边[因此WA掉1次 2.无权嘛,那么边长建成1就好了2333333 3.最短路采用迪杰斯特拉(别忘用堆优 ...
- 题解 Luogu P1110 【[ZJOI2007]报表统计】
感谢 @cmy962085349 提供的hack数据,已经改对了. 先声明,我好像是题解里写双$fhq$ $treap$里唯一能过的...(最后两个点啊) 思路:首先看题目,$MIN_GAP_SORT ...
- 题解 Luogu P3370
讲讲这题的几种做法: 暴力匹配法 rt,暴力匹配,即把字符串存起来一位一位判相等 时间复杂度$ O(n^2·m) $ 再看看数据范围 \(n\le10^5,m\le10^3\) 当场爆炸.当然有暴力分 ...
随机推荐
- 8Java设计模式(持续更新)
1.单例模式(Singleton pattern): 单例模式的实现方式是,一个类能返回对象的一个引用(永远是同一个)和一个获得该唯一实例的方法(必须是静态方法). 饿汉式: public class ...
- CH1809 匹配统计 题解
看了好久才懂,我好菜啊-- 题意:给两个字符串 \(a\) 与 \(b\),对于 \(q\) 次询问,每次询问给出一个 \(x\),求存在多少个位置使得 \(a\) 从该位置开始的后缀子串与 \(b\ ...
- 【洛谷P1962 斐波那契数列】矩阵快速幂+数学推导
来提供两个正确的做法: 斐波那契数列双倍项的做法(附加证明) 矩阵快速幂 一.双倍项做法 在偶然之中,在百度中翻到了有关于斐波那契数列的词条(传送门),那么我们可以发现一个这个规律$ \frac{F_ ...
- Linux bash命令行常用快捷键(Xshell和secure CRT以及gnome-terminal)
常用的命令行击键操作 ctrl + insert xshell中复制,可以设置选中内容自动复制ctrl shift + c crt中复制shift + insert xshell中粘贴ctrl s ...
- 基于小熊派Hi3861鸿蒙开发的IoT物联网学习【一】
基于小熊派鸿蒙季BearPi-HM_Nano HarmonyOS 鸿蒙系统Hi3861开发板NFC 开发步骤:1.购买开发板:某宝上购买就行 2.安装开发环境 3.下载源码 4.编写案例并执行 开发 ...
- Python - 基础数据类型 dict 字典
字典简介 字典在 Python 里面是非常重要的数据类型,而且很常用 字典是以关键字(键)为索引,关键字(键)可以是任意不可变类型 字典由键和对应值成对组成,字典中所有的键值对放在 { } 中间,每一 ...
- 小技巧 | Get 到一个 Web 自动化方案,绝了!
1. 前言 大家好,我是安果! 无论是 Chrome,还是 Firefox 浏览器,它们的强大性在很大程度上都是依赖于海量的插件,让我们能高效办公 那我们是否可以编写一个插件,让浏览器自动化完成一些日 ...
- 'Rem EverythingAutoSetup.VBS 安装Everything的VBS脚本 2019年11月25日写
'Rem EverythingAutoSetup.VBS 安装Everything的VBS脚本 2019年11月25日写 'Rem Everything是voidtools开发的一款本地NTFS文件和 ...
- dio框架访问云函数参数传递问题(以腾讯云中的云函数为例子)第一部
dd云函数其实比较普及,这里以腾讯云的云函数为例,传递参数完成简单的账号注册. 一.第一步先注册腾讯云账号,这里不过多阐述,接着点击 控制台 进入开发者界面.(注意提前进行实名认证) 二.开发者界面如 ...
- Java面向对象06——类与对象小结
小结 /* 1. 类与对象 类是一个模板:抽象,对象是一个具体的实例 2. 方法 定义.调用 3. 对应的引用 引用类型: 基本类型(8) 对象是通过引用来操作的:栈-- ...