2023牛客多校第二场 G Link with Centrally Symmetric String(类马拉车)

news2024/12/26 10:34:00

2023牛客多校第二场 G Link with Centrally Symmetric Strings(类马拉车 + 最长回文后缀)

题目链接

大意:定义对称回文的回文中心可以是

间隔(偶回文中心) 或者 o / x / s / z (奇回文中心) 五种 ,

定义匹配为 b/q d/p n/u o/o x/x s/s z/z 之间相互匹配 , 问给出的串是否是多个对称回文串的组合。

思路:题目很明显就是类马拉车的定义 , 以及巨大的数据量也在提示我们要用线性的做法去实现 , 考虑类马拉车。

那么如何判断一个串是否是由多个对称回文串拼接而成的呢?我们可以考虑从一个对称回文串的尾部跳到一个回文串的头部 , 从最后开始跳 , 如果能跳到字符串的开头就是一个 好的字符串 , 否则就是坏的。

在这里插入图片描述

显然一个位置可以有多个长度的回文串可以跳 , 如何抉择呢?这里我们选择一个串的最长回文后缀跳 , 可以证明这样跳一定是最优的 , 类马拉车预处理出每个位置作为前缀末尾可以往前跳的最长回文串的前端位置 , 依次往前跳即可 , 能跳到开头位置即为好串。复杂度O(N)

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
const int N = 2e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int,int>PII;
const double eps = 1e-9;

int d[N] , pre[N];

unordered_map<char,char>mp;
void init(){
	mp['b'] = 'q';mp['q'] = 'b';
	mp['d'] = 'p';mp['p'] = 'd';
	mp['n'] = 'u';mp['u'] = 'n';
	mp['o'] = 'o';mp['s'] = 's';
	mp['x'] = 'x';mp['z'] = 'z';
	mp['$'] = '$';
}//处理类回文串匹配

string manacher(string &s){
	
	string now = "#$";
	int n = s.size();
	for(int i = 0 ; i < n ; i ++) now += s[i] , now += '$';
	n = now.size();
	d[1] = 1;
	pre[1] = 1;//特殊处理 pre[1] , 避免跳到 0
	for(int i = 2 ; i < n ; i ++) pre[i] = 0;//pre数组记录当前节点能跳到的最前位置
	for(int i = 2 , l , r = 1; i < n ; i ++){
		if(now[i] != 'o' && now[i] != 's' && now[i] != 'x' && now[i] != 'z' && now[i] != '$'){
			d[i] = 0;continue;
		}//非对称中心位置特殊处理
		if(i <= r) d[i] = min(d[r - i + l] , r - i + 1);
		else d[i] = 1;
		while(mp[now[i - d[i]]] == now[i + d[i]] && i + d[i] < n && i - d[i] >= 0){
			d[i] += 1;
			pre[i + d[i] - 1] = i - d[i] + 1; 
		}//暴力匹配不断扩展的 r 对应的 l 就是最长回文前缀的位置
		if(i + d[i] - 1 > r) l = i - d[i] + 1 , r = i + d[i] - 1; 
	}
	return now;	
}

/*
qboqqbb
*/

void watch(string s){
	int n = s.size();
	for(int i = 0 ; i < n ; i ++) cout << s[i] << " ";
	cout << "\n"; 
	for(int i = 0 ; i < n ; i ++) cout << d[i] << " ";
	cout << "\n";
	for(int i = 0 ; i < n ; i ++) cout << pre[i] << " ";
	cout << "\n";
}

string s;
int t;

signed main(){

	IOS
	cin >> t;
	init();
	while(t --){
		
		cin >> s;
		string t = manacher(s);
		int n = t.size();
		int now = n - 1;
//		watch(t);
		
		while(pre[now] != now) now = pre[now];
		if(now == 1) cout << "Yes\n";
		else cout << "No\n";
	}

	
	return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/892488.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

nvm安装使用与常见问题

前言 nvm是一个用来进行nodejs多个版本管理和切换的工具。这个工具的使用相当简单和方便&#xff0c;但是没想到我使用的时候却遇到了好些问题&#xff0c;这里记录一下顺便分享。 安装nvm 先去下载地址Releases coreybutler/nvm-windows GitHub下载&#xff0c;建议选择下…

批量记录收支明细,轻松通过收支占比图表轻松分析支出项目占比!

您是否希望更加直观地了解个人或企业的支出项目占比情况&#xff1f;是否想通过图表分析&#xff0c;快速定位支出的主要项目&#xff0c;并做出相应的调整&#xff1f;现在&#xff0c;我们的智能收支分析大师为您提供了一种智能化的解决方案&#xff01;只需几步操作&#xf…

sliver C2 切换会话

使用中发现会话的切换直接输入sessions,显示会话 use 切换到新会话 在测试进程迁移的时候发现命令不好用 多次尝试,没有成功的

骨传导耳机戴久了头疼正常吗?骨传导耳机对健康有影响吗

骨传导耳机戴久了头疼正常吗&#xff1f;骨传导耳机对健康有影响吗 长时间佩戴骨传导耳机可能会引起一些人头疼的不适感&#xff0c;这可能是因为长时间的接触和震动影响了你的感知和舒适度。如果你遇到这样的问题&#xff0c;可以尝试以下几种解决方法&#xff1a; ⑴适当休…

第6章:支持向量机

间隔与支持向量 w为法向量&#xff0c;决定的是超平面的方向。b是偏移项&#xff0c;决定了超平面与原点之间的距离。 为什么最大化间隔&#xff0c;得到的就是最优平面呢&#xff1f; 当超平面没有正确划分正负样本时&#xff0c;几何间隔为负数。几何间隔&#xff0c;各个…

C++学习系列之DLL动态库使用

C学习系列之DLL动态库使用 啰嗦动态库的创建动态库的调用函数生成1.需要头文件函数定义&#xff08;头文件&#xff09;2.需要函数定义&#xff08;函数文件&#xff09;3.动态库中的头文件4.动态库中的主文件5.运行查看是否存在C#的调用的入口点6.C#调用 总结 啰嗦 项目需要&…

HSE是什么,好用的HSE系统推荐

阅读本文您将了解&#xff1a;1、HSE是什么&#xff1b;2、HSE在企业中的作用&#xff1b;3、好用的HSE系统推荐 一、HSE是什么 HSE是"Health, Safety, and Environment"&#xff08;健康、安全和环境&#xff09;的缩写。它指的是一个在工作场所、生产过程和社会活…

已解决:Module‘xxx’存在

1.问题如图&#xff0c;进入项目结构&#xff0c;找到模块检查是否仍有同名文件。 2.选中文件&#xff0c;点“—”号&#xff0c;应用&#xff0c;确定即可 3.重新新建即可成功。

【C语言程序设计】C语言基本数据类型与表达式(思考题)

思考题 1、C语言的主要特点有哪些&#xff1f; ①简单紧凑、灵活方便&#xff0c;②是结构化的语言&#xff0c;③运算符丰富&#xff0c;④是一种高效的语言&#xff0c;⑤可直接对硬件进行操作&#xff0c;⑥具有较好的可移植性。 高效性&#xff1a;C语言是一种高级编程语言…

VUE3 Hooks的面向对象实现方式

本文会以三种形式实现一个组件&#xff0c;该组件实现以下功能&#xff1a; 1.显示一个数字&#xff08;可从prop给初始值&#xff09;和一个添加按钮&#xff1b; 2.点击添加按钮数字增加&#xff1b; 3.当数字大于5时&#xff0c;数字颜色变红&#xff0c;并提交error事件…

Redis持久化——RDB快照

介绍 我们知道Redis是运行在内存中的数据库&#xff0c;那么当我们关闭Redis服务器后&#xff0c;内存中的数据会不会丢失&#xff1f; 当然是不会&#xff01;因为Redis有持久化机制&#xff0c;所谓持久化&#xff0c;就是将内存中的数据保存到磁盘文件上&#xff0c;以此来…

Zookeeper进阶篇 - Paxos协议算法、ZBA协议算法原理、Leader选举原理

Zookeeper底层原理篇&#xff0c;​让学习绚丽多彩起来&#xff01;&#xff01;&#xff01;

Eigen 的简单使用 与 轨迹拟合代码的理解

工作中遇到一个问题&#xff0c;发到hmi的车辆引导线为斜的&#xff0c;有一说一&#xff0c;仔细看下这段代码&#xff0c;发现用到了Eigen库用来多项式曲线拟合&#xff0c;线性回归&#xff0c;矩阵向量计算等。 #include <iostream> #include <vector> #inclu…

001-Nacos 服务注册

目录 Nacos介绍注册中心架构面临问题源码分析实例注册-接口实例注册-入口实例注册-创建一个(Nacos)Service实例注册-注册(Nacos)Service Nacos 介绍 Dynamic Naming and Configuration Service 动态的命名和配置服务 反正可以实现注册中心的功能 注册中心架构 服务提供者 …

做好需求分析的4大关键认知

探索如何正确的需求分析&#xff1f;本文详细介绍了4大关键点&#xff0c;帮助您明确用户与产品需求、深入挖掘用户动机&#xff0c;并为产品经理提供筛选需求的实用建议。 一、什么是需求分析以及重要性 需求分析指的是在建立一个新的或改变一个现存的产品时&#xff0c;确定新…

人工智能在网络安全中的应用: 分析人工智能、机器学习和深度学习等技术在预测、检测和应对网络攻击中的作用

第一章&#xff1a;引言 随着信息技术的迅猛发展&#xff0c;网络安全已成为当今社会不容忽视的重要议题。网络攻击手法日益复杂&#xff0c;传统的防御方法已经不再足够。在这一背景下&#xff0c;人工智能&#xff08;AI&#xff09;技术正逐渐崭露头角&#xff0c;为网络安…

vue3学习笔记(一)

一、API风格 Vue 的组件可以按两种不同的风格书写&#xff1a;选项式 API 和组合式 API。 二、组合式API 1.&#xff08;组合式 API 的核心思想是直接在函数作用域内定义响应式状态变量&#xff0c;并将从多个函数中得到的状态组合起来处理复杂问题。这种形式更加自由&#x…

SummaryWriter

SummaryWriter tb_writer SummaryWriter("swin_transformer_loss_acc") 第一个参数 log_dir : 用以保存summary的位置 add_scalar()函数的目的是添加一个标量数据&#xff08;scalar data&#xff09;到summary中 重要的常用的其实就是前三个参数&#xff1a; &…

【C++】模拟实现unordered_map和unordered_set

哈希表封装 前言正式开始模型修改Insert修改迭代器运算符重载 Findoperator[ ] 前言 本篇以前一篇模拟实现哈希表为基础进行改造&#xff0c;如果没看过前一篇的先看一下&#xff1a;【C】模拟实现哈希&#xff08;闭散列和开散列两种方式&#xff09;。 由于本篇代码基于上篇…

编译工具:CMake(五) | 静态库与动态库构建

编译工具&#xff1a;CMake&#xff08;五&#xff09; | 静态库与动态库构建 建立共享库编译共享库指令 ADD_LIBRARY 添加静态库动态库版本号安装共享库和头文件 建立共享库 在Compilation_tool/cmake路径下建立test3目录 在 t3 目录下建立 CMakeLists.txt&#xff0c;内容如…