牛客小白月赛91 ----- Bingbong的回文路径 ---- 题解

Bingbong的回文路径:

题目描述:

思路解析:

现在有一棵树,树上每个结点上都有一个小写字母,那么如果唯一确定了x和y两个结点,那么就唯一确定了一个字符串路径(最短路径)。 -现在给出q次查询,问x和y这个路径是否是回文字符串。

一看到回文字符串就可以应当想到字符串hash。但是怎么快速查询这个路径上字符串的hash值变成为了关键,可以发现,根节点到到任意结点的路径是确定的,并且是可以在一次dfs遍历中维护出来根据点到任意结点的字符串路径hash值的,那我们检查这个值有什么用。

假设我们查询红色结点到蓝色结点,那么可以发现,我们只需要找到他们最小公共祖先就可以利用他们三个结点的hash值来维护任意结点之间的hash值了。那么这道题就可以做了

代码实现:

import java.util.*;import java.io.*;public class Main {static long[] pow = new long[100005];static long[] inv = new long[100005];public static void main(String[] args) throws IOException {Random random = new Random();for (int i = 0; i < 26; i++) {s[i] = random.nextInt(10000);}pow[0] = 1;inv[0] = 1;long invb = qkm(base);for (int i = 1; i < 100005; i++) {pow[i] = pow[i - 1] * base % mod;inv[i] = inv[i - 1] * invb % mod;}int t = 1;while (t > 0) {solve();t--;}w.flush();w.close();}static char[] str;static int[] s = new int[26];static int mod = (int) 1e9 + 9;static int base = 131;static Vector<Integer>[] g;static int[] dep;static int[][] st;static long[] pre;static long[] suf;public static void solve() throws IOException {int n = f.nextInt();str = (" " + f.next()).toCharArray();g = new Vector[n+1];dep = new int[n+1];st = new int[n+1][20];pre = new long[n+1];suf = new long[n+1];for (int i = 0; i < n + 1; i++) {g[i] = new Vector<>();}for (int i = 1; i <= n; i++) {int x = f.nextInt();g[x].add(i);}dfs(1, 0);for (int j = 1; j < 20; j++) {for (int i = 1; i <= n; i++) {st[i][j] = st[st[i][j-1]][j-1];}}int q = f.nextInt();for (int i = 0; i < q; i++) {int x = f.nextInt(); int y = f.nextInt();if (check(x,y)) w.println("YES");else w.println("NO");}}public static boolean check(int x, int y){int fa = lca(x, y);long a = (pre[x] - (pre[fa] * pow[dep[x] - dep[fa]] % mod)) % mod;long b = (pre[y] - (pre[fa] * pow[dep[y] - dep[fa]] % mod)) % mod;long c = (suf[x] - suf[fa]) * inv[dep[fa]] % mod;long d = (suf[y] - suf[fa]) * inv[dep[fa]] % mod;a = (a + mod) % mod;b = (b + mod) % mod;c = (c + mod) % mod;d = (d + mod) % mod;long A = (s[str[fa] - 'a'] * pow[dep[x] - dep[fa]] % mod + a + d * pow[dep[x] - dep[fa] + 1] % mod) % mod;long B = (s[str[fa] - 'a'] * pow[dep[y] - dep[fa]] % mod + b + c * pow[dep[y] - dep[fa] + 1] % mod) % mod;return A == B;}public static int lca(int x, int y){if (dep[x] < dep[y]) {int tmp = x; x = y; y = tmp;}for (int i = 19; i >= 0; i--) {if (dep[st[x][i]] >= dep[y]){x = st[x][i];}}if (x == y) return x;for (int i = 19; i >= 0; i--) {if (st[x][i] != st[y][i]){x = st[x][i]; y = st[y][i];}}return st[x][0];}public static long qkm(long a){long res = 1;long b = mod - 2;while (b > 0){if ((b & 1) == 1) res = (res * a) % mod;a = a * a % mod;b >>= 1;}return res;}public static void dfs(int x, int fa){dep[x] = dep[fa] + 1;st[x][0] = fa;pre[x] = (pre[fa] * base % mod+ s[str[x]-'a']) % mod;suf[x] = (suf[fa] + s[str[x]-'a'] * pow[dep[fa]] % mod) % mod;for (int i = 0; i < g[x].size(); i++) {int y = g[x].get(i);if (y == fa) continue;dfs(y, x);}}static PrintWriter w = new PrintWriter(new OutputStreamWriter(System.out));static Input f = new Input(System.in);static class Input {public BufferedReader reader;public StringTokenizer tokenizer;public Input(InputStream stream) {reader = new BufferedReader(new InputStreamReader(stream), 32768);tokenizer = null;}public String next() throws IOException {while (tokenizer == null || !tokenizer.hasMoreTokens()) {tokenizer = new StringTokenizer(reader.readLine());}return tokenizer.nextToken();}public String nextLine() throws IOException {String str = null;str = reader.readLine();return str;}public int nextInt() throws IOException {return Integer.parseInt(next());}public long nextLong() throws IOException {return Long.parseLong(next());}public Double nextDouble() throws IOException {return Double.parseDouble(next());}}
}

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

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

相关文章

CSS 画一个三角形

一、前言 在前端开发的时候&#xff0c;我们有时候会需要用到一个三角形的形状&#xff0c;比如地址选择或者播放器里面播放按钮 通常情况下&#xff0c;我们会使用图片或者svg去完成三角形效果图&#xff0c;但如果单纯使用css如何完成一个三角形呢&#xff1f; 实现过程似…

3、MATLAB中矩阵和多维矩阵介绍

文章目录 一、矩阵二、矩阵举例三、定义变量四、定义矩阵五、获取变量值 一、矩阵 MATLAB中数据的基本格式是矩阵&#xff1b; 二维矩阵是一个带有以行和列排列的元素的矩阵表&#xff1b;如果右m行、n列&#xff0c;这个矩阵的大小就是m x n&#xff1b;多维矩阵的维数大于2…

[jinja2]模板访问对象属性

甚至可以用. 访问字典 .访问一般用得是最多的

单例模式可以被破坏

通过反射的方式破坏单例模式 解决&#xff1a;在构造函数中添加判断 private Singleton() {if (singleton ! null) {throw new RuntimeException("Singleton constructor is called... ");} } 序列化和反序列化破坏单例模式 解决&#xff1a;在Sinleton中增加rea…

【java解决线程间变量不可见性的方案】

解决线程间变量不可见性的方案 一、 背景 所有的实例变量和类变量都存储在主内存&#xff0c;但每个线程都有自己的工作内存&#xff0c;保留了主内存的共享变量的副本&#xff0c;线程修改的是共享变量&#xff0c;但是每个线程每次只能读取工作内存里的值&#xff0c;所以会…

Linux系统的账号和权限管理

目录 一、管理用户账号和组账号 1、useradd 2、passwd 3、usermod 4、userdel 二、管理目录和文件的属性 1、组账号管理 1&#xff09;groupadd 2&#xff09;gpasswd 3&#xff09;groupdel 4&#xff09;groups 2、文件权限 1&#xff09;chmod 2&#xff09…

【python】活学活用之字典用法实战——计数器

【python】活学活用之字典用法实战——计数器 字典也可以用作计数器。例如,我们可以使用字典来统计一段文本中每个单词出现的次数: # 定义一个名为 word_count 的函数,它接受一个参数:text def word_count(text):# 创建一个空字典,用于存储每个单词及其出现的次数counts…

Elasticsearch:(二)2.安装kibana

1.环境安装介绍: 安装java环境安装Elasticsearch安装kibana安装Elasticsearch-head插件 本节文章主要讲解kibana的安装。 2.下载 下载Elasticsearch对应的版本,参考官方自身产品兼容版本:支持一览表 | Elastic 下载地址:Kibana 7.17.20 | Elastic Kibana 7.17.20 | Ela…

操作教程丨MaxKB+Ollama:快速构建基于大语言模型的本地知识库问答系统

2024年4月12日&#xff0c;1Panel开源项目组正式对外介绍了其官方出品的开源子项目——MaxKB&#xff08;github.com/1Panel-dev/MaxKB&#xff09;。MaxKB是一款基于LLM&#xff08;Large Language Model&#xff09;大语言模型的知识库问答系统。MaxKB的产品命名内涵为“Max …

C++ stl容器stack,queue,priority_queue的底层模拟实现

目录 前言&#xff1a; 文档借鉴&#xff1a;Reference - C Reference 1.deque a.deque的结构特点&#xff1a; b.deque的迭代器结构&#xff1a; c.面试题&#xff1a; 2.stack 3.queue 4.仿函数 5.priority_queue 总结&#xff1a; 前言&#xff1a; 本篇一共简单…

04节-51单片机-数码管模块

1.静态数码管显示 LED数码管&#xff1a;数码管是一种简单、廉价的显示器&#xff0c;是由多个发光二极管封装在一起组成“8”字型的器件 下图展示了数码管的线路连接 数码管的连接方式分为&#xff0c;公共端&#xff0c;共阴极和共阳极连接&#xff1a; 多个数码管共用引…

存储过程的查询

Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 在实际使用中&#xff0c;经常会需要查询数据库中已有的存储过程或者某一个存储过程的内容&#xff0c; 下面就介绍-下如何查询存储过程。 这需要使用到数据字典 user_sou…

MacBook系统升级导致idea无法打开

1 背景 MacBook的MacOS系统升级之后&#xff0c;之前安装的idea无法打开了。idea卸载重装仍然无法打开。 2 原因排查 2.1 寻找报错原因 为了了解具体的报错原因&#xff0c;通过“访达-应用程序”找到“IntelliJ IDEA”&#xff0c;然后右击打开“显示包内容”选项进入Intel…

Linux设置真实IP

1.查看ens33网卡信息 vi /etc/sysconfig/network-scripts/ifcfg-ens33 #添加以下内容 BOOTPROTODHCP #协议类型 dhcp bootp none ONBOOTyes #启动时是否激活 yes | no#修改文件完成后&#xff0c;重启网络 service network restartping www.baidu.com #验证网络是否生效 ifco…

宝塔面板国际版aaPanel 精简版安装

宝塔面板国际版aaPanel 精简版安装 很多人都知道宝塔面板&#xff0c;但不知道宝塔面板还有英文版&#xff0c;宝塔面板英文版不是单纯的宝塔面板的翻译&#xff0c;而是根据老外的使用习惯及国外的网络环境做了一定的优化&#xff0c; 比如&#xff1a;去掉了手机号验证、去…

【大语言模型LLM】-大语言模型如何编写Prompt?

第一部分 环境配置 1.1 安装 Anaconda 官网&#xff1a;Anaconda清华源镜像&#xff1a;Anaconda推荐安装版本&#xff1a;Anaconda Python 3.11 1.2 创建虚拟环境 打开&#xff1a;anaconda prompt创建名为env_name的虚拟环境&#xff1a;conda create -n env_name python…

数据结构----顺序表

在学习顺序表之前&#xff0c;我们先来了解一下数据结构。 数据是什么呢&#xff1f; 我们在生活中常见的名字&#xff0c;数字&#xff0c;性别等都属于数据。 结构又是什么呢&#xff1f; 在计算机中&#xff0c;结构就是用来保存数据的方式。 总的来说&#xff0c;数据…

【Cookie,Session,Token,JWT的区别】

一、Cookie Cookie 是在 HTTP 协议下&#xff0c;维护客户工作站上信息的一种方式。Cookie 是由 Web 服务器保存在用户浏览器上的小文本数据文件&#xff0c;它可以包含有关用户的信息。cookie是不可跨域的&#xff0c;每个cookie都会绑定一个单一的域名&#xff0c;并只能在指…

Python 基础02-Python 入门

官方文档&#xff1a;3.10.13 Documentation 一、Python 代码编写习惯 1. Python 中的编码 在 Python 3 版本之后&#xff0c;Python 默认使用 UTF-8 编码。UTF-8 是一种针对 Unicode 的可变长度字符编码。 2. 注释 注释可以对代码起到解释说明的作用&#xff0c;注释内容…

Linux的启动过程,了解一下?

Linux 系统启动过程 linux启动时我们会看到许多启动信息。 Linux系统的启动过程并不是大家想象中的那么复杂&#xff0c;其过程可以分为5个阶段&#xff1a; 内核的引导。运行 init。系统初始化。建立终端 。用户登录系统。 init程序的类型&#xff1a; SysV: init, CentO…