首页 > 其他分享 >Luogu P5446 [THUPC2018] 绿绿和串串

Luogu P5446 [THUPC2018] 绿绿和串串

时间:2023-06-08 16:58:13浏览次数:40  
标签:绿绿 int Luogu len lhzawa text P5446 cu 翻转

根据题目能发现一个性质,设转化前的字符串为 \(s\),转化后的字符串为 \(s'\),则 \(s'_{|s|}\) 为 \(s'\) 的中心,即 \(s'_{|s|}\) 求出来的回文串左边界为 \(1\) 右边界为 \(|s'|\)

找出这个性质就挺简单了,考虑先对给出的 \(S\) 用 \(\text{manacher}\) 求出每个节点 \(i\) 对应的左边界 \(l_i\) 右边界 \(r_i\),然后对于原串 \(R\) 分两种情况讨论:

  1. \(\text{lhzawa}\to \text{lhzawawa}\),即 \(R\) 翻转过来但是有部分后缀被删了,此时对应在 \(S\) 中对应的 \(r_{|R|} = |S|\),因为至少还在的部分是回文的。
    需注意这种情况只会在最后一次变换为 \(S\) 时出现,前面的变换出来的结果肯定是完整串(或前面没有进行变换)。
  2. \(\text{lhzawa}\to \text{lhzawawazhl}\),即 \(R\) 翻转为 \(S\) 后是完整的,此时因为 \(R\) 一定为前缀所以 \(l_{|R|} = 1\) 且 \(r_{|R|}\) 对应的也是一个可以字符串翻转为 \(S\) 的字符串 \(R'\),这样才能保证经过后面的翻转能变为 \(S\)。

所以这个题基本上就搞定啦,步骤顺序从后往前,先特殊判断 1 情况,再由每一个之前得到的点按照 2 情况继续往前推。
因为能发现假设现在一个合法的点 \(u\),则其可以推到的点为 \(\lceil\frac{u}{2}\rceil\),因为 \(S_{1\sim u}\) 若能继续分下去且合法则定为一个奇回文串,找到中点即可。
于是就实现了一个类似 \(\text{BFS}\) 的过程,时间复杂度 \(\mathcal{O}(\sum|s|)\)。

需要注意的点:多测清空。

// lhzawa(https://www.cnblogs.com/lhzawa/)
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
char s[N];
int len[N];
int cu[N];
int main() {
	function<void ()> solve = []() -> void { 
		scanf("%s", s + 1);
		int n = strlen(s + 1);
		s[0] = '&', s[n + 1] = '$';
		int mid = 0, mx = 0;
		for (int i = 1; i <= n; i++) {
			if (i < mx) {
				len[i] = min(len[mid * 2 - i], mx - i);
			}
			else {
				len[i] = 0;
			}
			for (; s[i - len[i]] == s[i + len[i]]; len[i]++);
			if (i + len[i] > mx) {
				mx = i + len[i], mid = i;
			}
		}
		for (int i = 1; i <= n; i++) {
			cu[i] = 0;
		}
		queue<int> q;
		for (int i = 1; i <= n; i++) {
			len[i]--;
		}
		// for (int i = 1; i <= n; i++) {
		// 	printf("%d ", len[i]);
		// }
		// printf("\n");
		for (int i = n; i >= 1; i--) {
			if (i + len[i] == n) {
				q.push(i);
			}
		}
		for (; ! q.empty(); ) {
			int u = q.front();
			q.pop();
			cu[u] = 1;
			if (u & 1) {
				int v = (u >> 1) + 1;
				if (! cu[v] && v + len[v] >= u && len[v]) {
					q.push(v);
				}
			}
		}
		for (int i = 1; i <= n; i++) {
			if (cu[i]) {
				printf("%d ", i);
			}
		}
		printf("\n");
	};
	int Tcs;
	scanf("%d", &Tcs);
	for (; Tcs; Tcs--) {
		solve();
	}
	return 0;
}

标签:绿绿,int,Luogu,len,lhzawa,text,P5446,cu,翻转
From: https://www.cnblogs.com/lhzawa/p/17466999.html

相关文章

  • Luogu P3224 [HNOI2012]永无乡
    [HNOI2012]永无乡题目描述永无乡包含\(n\)座岛,编号从\(1\)到\(n\),每座岛都有自己的独一无二的重要度,按照重要度可以将这\(n\)座岛排名,名次用\(1\)到\(n\)来表示。某些岛之间由巨大的桥连接,通过桥可以从一个岛到达另一个岛。如果从岛\(a\)出发经过若干座(含\(0\)......
  • [刷题笔记] Luogu P3073 [USACO13FEB]Tractor S
    ProblemSolution和汽车拉力比赛差不多,思路都是二分,二分\(d\),但是汽车拉力比赛从一个路标开始搜即可,本题没有给定起点。一条合法路径起点是未知的,不得随便从一个点开始搜,否则可能找不到正确路径。怎么处理呢?容易想到对于每一个二分的\(d\),开一个\(n^2\)的循环,从每一个点开始搜......
  • Luogu P3605 [USACO17JAN]Promotion Counting P
    [USACO17JAN]PromotionCountingP题目描述Thecowshaveonceagaintriedtoformastartupcompany,failingtorememberfrompastexperiencethatcowsmaketerriblemanagers!Thecows,convenientlynumbered\(1\ldotsN\)(\(1\leqN\leq100,000\)),o......
  • Luogu P4556 [Vani有约会]雨天的尾巴 /【模板】线段树合并
    [Vani有约会]雨天的尾巴/【模板】线段树合并题目背景深绘里一直很讨厌雨天。灼热的天气穿透了前半个夏天,后来一场大雨和随之而来的洪水,浇灭了一切。虽然深绘里家乡的小村落对洪水有着顽固的抵抗力,但也倒了几座老房子,几棵老树被连根拔起,以及田地里的粮食被弄得一片狼藉。无奈......
  • LuoguP4318 完全平方数
    标签:莫比乌斯函数,容斥完全平方数题目描述小X自幼就很喜欢数。但奇怪的是,他十分讨厌完全平方数。他觉得这些数看起来很令人难受。由此,他也讨厌所有是完全平方数的正整数倍的数。然而这丝毫不影响他对其他数的热爱。这天是小X的生日,小W想送一个数给他作为生日礼物。当然他......
  • Luogu P2709 小B的询问
    https://www.luogu.com.cn/problem/P2709#submit小B的询问题目描述小B有一个长为\(n\)的整数序列\(a\),值域为\([1,k]\)。他一共有\(m\)个询问,每个询问给定一个区间\([l,r]\),求:\[\sum\limits_{i=1}^kc_i^2\]其中\(c_i\)表示数字\(i\)在\([l,r]\)中的出现次数......
  • [刷题笔记] Luogu P2895 Meteor Shower S
    ProblemSolution显然bfs,只不过有了限定条件,有实时的流星雨这里提供两种做法:Solution1这也是我一开始的做法模拟实时流星,由于bfs是按层搜的,是严格按照时间递增搜的,故可以模拟实时放流星。需要注意放流星的时间,如果第\(t\)秒有流星,则该秒不可以走,需要在每一秒前放流星。那......
  • [刷题笔记] LuoguP2658 汽车拉力比赛
    ProblemSolution需要找到最小满足题意的\(d\),显然\(d\)满足单调性,考虑二分二分\(d\),然后直接bfs,每次bfs判断能不能走的时候还需要加上高度差不超过二分的\(d\)(即满足),bfs跑完后看看所有的路标都被访问了没。(可以记录个数,因为不可能重复走)二分的时候注意\(l\)从0开始,不然会WA......
  • luogu P8497 [NOI2022] 移除石子
    题面传送门不好评价?首先我们考虑最基础的情况,当\(k=0,l_i=r_i\)时,相当于我们需要判定一个状态能不能被消完。这相当于我们要执行若干次\(2\)操作,使得每个位置要么大于等于\(2\),要么为\(0\)。为此我们需要挖掘一些操作\(2\)的性质。性质\(1\):操作区间长度不会超过\(5......
  • Luogu P1007 独木桥
    题目描述link思路找到独木桥的中间位置,最少时间考虑在端点左侧的,向左走,在端点右侧的向右走.最多时间考虑在端点左侧的向右走,在端点右侧的向左走.最少时间即为最优情况下最多的时间,最多时间即为最差情况下的最多时间Code#include<cstdio>#include<algorithm>......