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

2024-04-21 18:12

本文主要是介绍牛客小白月赛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());}}
}

这篇关于牛客小白月赛91 ----- Bingbong的回文路径 ---- 题解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/923740

相关文章

Linux修改pip和conda缓存路径的几种方法

《Linux修改pip和conda缓存路径的几种方法》在Python生态中,pip和conda是两种常见的软件包管理工具,它们在安装、更新和卸载软件包时都会使用缓存来提高效率,适当地修改它们的缓存路径... 目录一、pip 和 conda 的缓存机制1. pip 的缓存机制默认缓存路径2. conda 的缓

Windows系统下如何查找JDK的安装路径

《Windows系统下如何查找JDK的安装路径》:本文主要介绍Windows系统下如何查找JDK的安装路径,文中介绍了三种方法,分别是通过命令行检查、使用verbose选项查找jre目录、以及查看... 目录一、确认是否安装了JDK二、查找路径三、另外一种方式如果很久之前安装了JDK,或者在别人的电脑上,想

Python中Windows和macOS文件路径格式不一致的解决方法

《Python中Windows和macOS文件路径格式不一致的解决方法》在Python中,Windows和macOS的文件路径字符串格式不一致主要体现在路径分隔符上,这种差异可能导致跨平台代码在处理文... 目录方法 1:使用 os.path 模块方法 2:使用 pathlib 模块(推荐)方法 3:统一使

一文教你解决Python不支持中文路径的问题

《一文教你解决Python不支持中文路径的问题》Python是一种广泛使用的高级编程语言,然而在处理包含中文字符的文件路径时,Python有时会表现出一些不友好的行为,下面小编就来为大家介绍一下具体的... 目录问题背景解决方案1. 设置正确的文件编码2. 使用pathlib模块3. 转换路径为Unicod

C++实现回文串判断的两种高效方法

《C++实现回文串判断的两种高效方法》文章介绍了两种判断回文串的方法:解法一通过创建新字符串来处理,解法二在原字符串上直接筛选判断,两种方法都使用了双指针法,文中通过代码示例讲解的非常详细,需要的朋友... 目录一、问题描述示例二、解法一:将字母数字连接到新的 string思路代码实现代码解释复杂度分析三、

MySQL9.0默认路径安装下重置root密码

《MySQL9.0默认路径安装下重置root密码》本文主要介绍了MySQL9.0默认路径安装下重置root密码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录问题描述环境描述解决方法正常模式下修改密码报错原因问题描述mysqlChina编程采用默认安装路径,

python获取当前文件和目录路径的方法详解

《python获取当前文件和目录路径的方法详解》:本文主要介绍Python中获取当前文件路径和目录的方法,包括使用__file__关键字、os.path.abspath、os.path.realp... 目录1、获取当前文件路径2、获取当前文件所在目录3、os.path.abspath和os.path.re

hdu2544(单源最短路径)

模板题: //题意:求1到n的最短路径,模板题#include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#i

csu1328(近似回文串)

题意:求近似回文串的最大长度,串长度为1000。 解题思路:以某点为中心,向左右两边扩展,注意奇偶分开讨论,暴力解即可。时间复杂度O(n^2); 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring>#include<string>#inclu

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO