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

news2024/11/16 10:48:04

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.coloradmin.cn/o/1612254.html

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

相关文章

linux内核初始化成功后是如何过渡到android初始化的

Android用的linux内核&#xff0c;以完成OS该有的功能&#xff0c;例如&#xff0c;文件系统&#xff0c;网络&#xff0c;内存管理&#xff0c;进程调度&#xff0c;驱动等 &#xff0c;向下管理硬件资源向上提供系统调用。另一些Android特有驱动也放在内核之中。 当linux内核…

Vue3+TS版本Uniapp:封装uni.request请求配置

作者&#xff1a;前端小王hs 阿里云社区博客专家/清华大学出版社签约作者✍/CSDN百万访问博主/B站千粉前端up主 封装请求配置项 封装拦截器封装uni.request 封装拦截器 uniapp的封装逻辑不同于Vue3项目中直接使用axios.create()方法创建实例&#xff08;在create方法中写入请求…

ChatGPT基础(三) 让ChatGPT回答质量提高十倍的提示词模版

上篇文章介绍了ChatGPT使用提示词的一些方法策略和如何优化我们的提示词。这里呢&#xff0c;我介绍一下参照大佬的方法总结的一个提示词的一个用法的模板。使用这个模板之后&#xff0c;我们的提问和获得答案的效率和收集素材的完整度能提高很多。 首先我介绍一下这个模板&am…

实战|哈尔滨等保2.0 Linux主机测评过程之身份鉴别

一、身份鉴别 a)应对登录的用户进行身份标识和鉴别&#xff0c;身份标识具有唯一性&#xff0c;身份鉴别信息具有复杂度要求并定期更换。 输入 more /etc/shadow,得知系统所有用户&#xff0c;此语句字段格式有九段。 第一字段&#xff1a;用户名&#xff08;也被称为登录名…

Nature Communications 构筑了具备优异形状记忆功能的聚合物材料

2024年2月29日&#xff0c;华东理工大学化学与分子工程学院、费林加诺贝尔奖科学家联合研究中心曲大辉教授团队在形状记忆功能聚合物材料研究中取得新进展&#xff0c;相关研究成果发表于《自然通讯》&#xff0c;这项研究取得了在形状记忆功能聚合物材料领域的新进展。研究团队…

国内ai人工智能软件大全

很多人一直在寻找一个稳定且可靠的全球AI大模型测试平台&#xff0c;希望它不仅真实可信&#xff0c;而且能提供稳定、快速的服务&#xff0c;不会频繁出现故障或响应缓慢。迄今为止&#xff0c;我已经尝试了国内外至少10个不同的服务站点。不幸的是&#xff0c;这些站点总是存…

【UE 材质】雨滴效果

在上一篇博客&#xff08;【UE 材质】表面湿润效果&#xff09;的基础上继续实现物体表面附加雨滴的效果 效果 步骤 1. 下载所需纹理 2. 创建一个材质并打开&#xff0c;添加如下节点&#xff0c;我们将纹理的RG通道输出的值和1组成一个三维向量&#xff0c;作为基本的法线效…

Shapley量化调峰成本?高比例可再生能源电力系统的调峰成本量化与分摊模型程序代码!

前言 在能源安全、环境污染和气候变化的大背景下&#xff0c;大力发展可再生能源是应对全球气候变化&#xff0c;实现“碳达峰、碳中和”和可持续发展的重大需求。截至2020年底&#xff0c;中国风电总装机容量为281GW&#xff0c;风力发电466.5TWh&#xff0c;同比增长约15%&a…

Reddit数据API 获取reddit的帖子、评论、按关键字搜索

近期调研发现 iDataRiver平台 https://www.idatariver.com/zh-cn/ 提供开箱即用的Reddit数据采集API&#xff0c;是目前用下来最方便简单的API&#xff0c;可以抓取 reddit 公开数据&#xff0c;例如 subreddit 中的帖子、按关键字搜索以及文章评论等&#xff0c;供用户按需调用…

【算法】实验室2024第一次考核复盘

【算法】实验室2024第一次考核复盘 本篇博客将遵循从易到难的原则&#xff0c;依次解析这几道考核题目。 原题链接&#xff1a; 125. 验证回文串 - 力扣&#xff08;LeetCode&#xff09; 使用两个指针i和j分别从字符串的两端开始&#xff0c;i从左往右&#xff0c;j从右往左。…

MySQL如何避免全表扫描?

MySQL如何避免全表扫描&#xff1f; 这篇文章解释了何时以及为什么MySQL会执行全表扫描来解析查询&#xff0c;以及如何避免在大型表上进行不必要的全表扫描。 何时会发生全表扫描 MySQL使用全表扫描&#xff08;在EXPLAIN输出中的type列显示为ALL&#xff09;来解析查询的几…

继东风一汽通信后,天磊咨询再次与东风集团达成深度业务合作

&#xff08;天磊咨询总经理&#xff1a;刘文喜&#xff09; 在风起云涌的市场激战中&#xff0c;天磊咨询凭借其出类拔萃的专业实力与服务品质&#xff0c;犹如一颗璀璨明星般脱颖而出&#xff0c;成功与赫赫有名的东风集团达成业务合作。这一合作的达成&#xff0c;不单彰显…

用java实现PDF的下载

1.下载PDF模版 2.导入依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itext7-core</artifactId><version>7.2.5</version><type>pom</type></dependency> 3.完整代码 package com.by.controller…

数据存储的大小端和测试程序

1.引言 计算机和嵌入式产品中数据的存储方式分为大端和小端两种方式。为什么呢&#xff1f;因为对于大多数设备都需要存储超过1个字节的数据单元。比如&#xff0c;你要表达0x12345678这个数字。使用1个字节的存储空间是肯定完成不了的。因此&#xff0c;你必须使用4个字节的空…

Postgres数据库中的死锁是如何产生的,如何避免和解决?

文章目录 死锁的产生原因如何避免死锁如何解决死锁示例代码查询死锁信息终止事务 在Postgres数据库中&#xff0c;死锁是一种特殊的情况&#xff0c;其中两个或多个事务相互等待对方释放资源&#xff0c;从而导致它们都无法继续执行。这种情况通常发生在多个事务尝试以不同的顺…

HarmonyOS NEXT 使用Canvas实现模拟时钟案例

介绍 本示例介绍利用 Canvas 和定时器实现模拟时钟场景&#xff0c;该案例多用于用户需要显示自定义模拟时钟的场景。 效果图预览 使用说明 无需任何操作&#xff0c;进入本案例页面后&#xff0c;所见即模拟时钟的展示。 使用说明 无需任何操作&#xff0c;进入本案例页…

2024化工制造企业数字化白皮书

来源&#xff1a;蓝凌研究院 中国石油和化学工业联合会发布2023年中国石油和化工行业经济运行情况。数据显示&#xff0c;2023年&#xff0c;我国石化行业实现营业收入15.95万亿元&#xff0c; 同比下降1.1%&#xff0c;利润总额8733.6亿元&#xff0c;行业经济运行总体呈现低…

FastJson2中FastJsonHttpMessageConverter找不到类问题

问题描述 如果你最近也在升级FastJson到FastJson2版本&#xff0c;而跟我一样也遇到了FastJsonHttpMessageConverter找不到类问题以及FastJsonConfig找不到问题&#xff0c;那么恭喜你&#xff0c;看完本文&#xff0c;安装完fastjson2、fastjson2-extension、fastjson2-exte…

Ubuntu 安装 wine

本文所使用的 Ubuntu 系统版本是 Ubuntu 22.04 ! 如果你使用 Ubuntu 系统&#xff0c;而有些软件只在 Windows 上运行&#xff0c;例如&#xff1a;PotPlayer&#xff0c;那么该如何在 Ubuntu 系统中使用到这些 Windows 的软件呢&#xff1f;答案是安装 wine。 简单的安装步骤如…

ZeRO论文阅读

一.前情提要 1.本文理论为主&#xff0c;并且仅为个人理解&#xff0c;能力一般&#xff0c;不喜勿喷 2.本文理论知识较为成体系 3.如有需要&#xff0c;以下是原文&#xff0c;更为完备 Zero 论文精读【论文精读】_哔哩哔哩_bilibili 二.正文 1.前言 ①为什么用该技术&…