Bingbong的回文路径

Here

  • 利用回文串,从左往右与从右往左的hash值相同来判断
  • 从左往右,例:bccb=>p^3+2p^2+2p+1
  • 从右往左,例:bccb=>1+2p+2p^2+p^3
  • 由于在树上,考虑建两颗树,一颗根为最高位(up),一棵根为最低位(down)
  • 考虑bccb(1,2,3,4)这个
  • (4,3,2,1)=>down(3,2,1)*p^{(weiup=1)}+up(4)
  • down(3,2,1)=>[(p^3+2p^2+2p+3)-(3)]*(1/p)=p^2+2p+2,即bcc
  • up(4)=>(3p^2+2p+1)-(3p+2)*(p)=1,即b
  • (4,3,2,1)=(p^2+2p+2)*p+1=p^3+2p^2+2p+1
  • 所以设在树上两点(u,v),LCA=x
  • v\rightarrow x\rightarrow u
  • down(x,u)=[down(u)-down(fa[x])]*inv(dep[x])(乘inv使x为最低位)
  • up(x,v)=up(v)-up(x)*(dep[v]-dep[x])
  • weiup=dep[v]-dep[x]
  • v\rightarrow x\rightarrow u=down(x,u)*p^{weiup}+up(x,v)
  • u\rightarrow x\rightarrow v,swap(u,v)即可
  • 为保证hash的正确性,采用双哈希,base=(29,131),mod=(1e9+7,1e9+9)

import java.io.*;
import java.math.BigInteger;
import java.util.*;


//implements Runnable
public class Main {
    static long md1=(long)1e9+7;
    static long md2=(long)1e9+9;
    static long Linf=Long.MAX_VALUE/2;
    static int inf=Integer.MAX_VALUE/2;
    static int N=200010;
    static int n=0;
    static int m=0;


    static
    class M{
        long x,y;
        public M(){};
        public M(long u,long v){
            x=u;y=v;
        }
    }
    static M mul(M a,M b){
        return new M(a.x*b.x%md1,a.y*b.y%md2);
    }
    static M add(M a,M b){
        return new M((a.x+b.x)%md1,(a.y+b.y)%md2);
    }
    static M sub(M a,M b){
        return new M((a.x-b.x+md1)%md1,(a.y-b.y+md2)%md2);
    }
    static M[] inv;
    static M[] fac;
    static M base=new M(29,131);
    static long qm2(long a,long b,long md){
        long res=1;
        while(b>0){
            if((b&1)==1)res=res*a%md;
            a=a*a%md;
            b>>=1;
        }
        return res;
    }
    static void getFac(){
       fac[0]=new M(1,1);
       up[0]=new M(0,0);
       down[0]=new M(0,0);
       for(int i=1;i<=n;++i){
           fac[i]=mul(fac[i-1],base);
       }
       inv[n]=new M();
       inv[n].x=qm2(fac[n].x,md1-2,md1);
       inv[n].y=qm2(fac[n].y,md2-2,md2);
       for(int i=n-1;i>=0;i--){
           inv[i]=mul(inv[i+1],base);
       }
    }
    static
    class Edge{
        int fr,to,nxt;
        public Edge(int u,int v){
            fr=u;to=v;
        }
    }
    static Edge[] e;
    static int[] head;
    static int cnt=0;
    static void addEdge(int fr,int to){
        cnt++;
        e[cnt]=new Edge(fr,to);
        e[cnt].nxt=head[fr];
        head[fr]=cnt;
    }
    static int[] fa;
    static int[] son;
    static int[] siz;
    static int[] dep;
    static int[] top;
    static M[] down;
    static M[] up;
    static int[] a;
    static void dfs1(int x,int f){
        siz[x]=1;dep[x]=dep[f]+1;fa[x]=f;
        up[x]=add(mul(up[f],base),new M(a[x],a[x]));
        down[x]=add(down[f],mul(new M(a[x],a[x]),fac[dep[x]]));
        for(int i=head[x];i>0;i=e[i].nxt){
            int v=e[i].to;
            if(v==f)continue;
            dfs1(v,x);
            siz[x]+=siz[v];
            if(siz[son[x]]<siz[v])son[x]=v;
        }
    }
    static void dfs2(int x,int tp){
        top[x]=tp;
        if(son[x]!=0)dfs2(son[x],tp);
        for(int i=head[x];i>0;i=e[i].nxt){
            int v=e[i].to;
            if(v==fa[x]||v==son[x])continue;
            dfs2(v,v);
        }
    }
    static int LCA(int x,int y){
        while(top[x]!=top[y]){
            if(dep[top[x]]>dep[top[y]]){
                int t=x;x=y;y=t;
            }
            y=fa[top[y]];
        }
        if(dep[x]>dep[y]){
            int t=x;x=y;y=t;
        }
        return x;
    }
    static M getHash(int u,int v,int x){

        M ux=mul(sub(down[u],down[fa[x]]),inv[dep[x]]);
        M xv=sub(up[v],mul(up[x],fac[dep[v]-dep[x]]));
        return add(mul(ux,fac[dep[v]-dep[x]]),xv);//从右上左下
    }
    static void getPre(){
        fac=new M[n+1];
        inv=new M[n+1];
        fa=new int[n+1];
        son=new int[n+1];
        siz=new int[n+1];
        dep=new int[n+1];
        top=new int[n+1];
        head=new int[n+1];
        e=new Edge[2*n+10];
        cnt=0;
        down=new M[n+1];//rha
        up=new M[n+1];//ha
        a=new int[n+1];
    }
    static void solve() throws Exception{
        AReader input=new AReader();
//        String fileName="";
//		Scanner input=new Scanner(new FileReader(fileName));

//        BufferedReader input = new BufferedReader(new FileReader(fileName));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        String al="abcdefghijklmnopqrstuvwxyz";
        char[] ac=al.toCharArray();
        n=input.nextInt();
        getPre();
        getFac();
        String string=" "+input.next();
        char[] s=string.toCharArray();
        for(int i=1;i<=n;++i){
            a[i]=s[i]-'a'+1;
        }
        for(int i=1;i<=n;++i){
            int x=input.nextInt();
            addEdge(x,i);
            addEdge(i,x);
        }
        dep[0]=-1;
        dfs1(1,0);
        dfs2(1,1);
        m=input.nextInt();
        while(m>0){
            m--;
            int x=input.nextInt();
            int y=input.nextInt();
            int p=LCA(x,y);
            M rtol=getHash(x,y,p);
            M ltor=getHash(y,x,p);
            if(rtol.x==ltor.x&&rtol.y==ltor.y)out.println("YES");
            else out.println("NO");
        }
        out.flush();
        out.close();
    }
    public static void main(String[] args) throws Exception{
        solve();
    }
    //	public static final void main(String[] args) throws Exception {
//		  new Thread(null, new Tx2(), "线程名字", 1 << 27).start();
//	}
//		@Override
//		public void run() {
//			try {
//				//原本main函数的内容
//				solve();
//
//			} catch (Exception e) {
//			}
//		}
    static
    class AReader{
        BufferedReader bf;
        StringTokenizer st;

        public AReader(){
            bf=new BufferedReader(new InputStreamReader(System.in));
            st=new StringTokenizer("");
        }
        public String nextLine() throws IOException{
            return bf.readLine();
        }
        public String next() throws IOException{
            while(!st.hasMoreTokens()){
                st=new StringTokenizer(bf.readLine());
            }
            return st.nextToken();
        }
        public char nextChar() throws IOException{
            //确定下一个token只有一个字符的时候再用
            return next().charAt(0);
        }
        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());
        }
        public float nextFloat() throws IOException{
            return Float.parseFloat(next());
        }
        public byte nextByte() throws IOException{
            return Byte.parseByte(next());
        }
        public short nextShort() throws IOException{
            return Short.parseShort(next());
        }
        public BigInteger nextBigInteger() throws IOException{
            return new BigInteger(next());
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

0 transformers入门,HuggingFace!

目录 1 了解 2 文本分类 1 了解 1 依赖安装 !pip install transformers -i https://pypi.tuna.tsinghua.edu.cn/simple some-package 2 了解transformers 能做什么 from transformers.pipelines import SUPPORTED_TASKS SUPPORTED_TASKS.items()2 文本分类 我没外网所以…

微信小程序 讯飞录音 点击按钮录音内容转文字

<page-meta page-style"{{ showPolish ? overflow: hidden; : }}" /> <view class"wrap"> <view class"header-tab" style"justify-content: {{typeList.length > 2 ? start : center}}"><view class&quo…

promise笔记

1.介绍 之前的异步编程都是回调函数&#xff08;数据库操作、ajax、定时器、fs读取文件 &#xff09; promise是es6异步编程新的解决方案&#xff0c;是一个构造函数 优点&#xff1a;支持链式调用&#xff0c;可以解决回调地狱&#xff0c;可以指定回调函数 2.使用 functio…

UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0xd7

安装mamba时报错 检查报错原因&#xff1a; file -i ~/.bashrc file -i ~/.profile发现bashrc的编码不正确 对编码格式进行修改 iconv -f ISO-8859-1 -t UTF-8 ~/.bashrc > ~/.bashrc.utf8 mv ~/.bashrc.utf8 ~/.bashrc cp ~/.bashrc ~/.bashrc.backup执行完指令之后再安…

SAM5916B 法国追梦DREAM 音频DSP芯片

法国追梦/DERAM SAM5504/5704/5716/5808音频DSP芯片,开发板&#xff0c;方案 可用于电子鼓、电子琴、电吉他、效果器、均衡器、啸叫抑制器等电声产品领域 一、全系列芯片&#xff1a; SAM2634 SAM2695 SAM5504B SAM5704B SAM5708B SAM5808B SAM5716B SAM5916B... 二、原厂开发套…

在matplotlib中控制colorbar的长度

在matplotlib中控制colorbar的长度 使用matplotlib绘制带颜色的箭头图&#xff0c;有时想直接把颜色条拿来当比例尺条&#xff0c;就需要控制颜色条的长度。 1. pyplot.colorbar()参数说明 pyplot.colorbar(mappable, ax, cax, **kwargs) mappable是一个ScalarMappble类型的…

【黑马头条】-day12项目部署和发布-jenkins

文章目录 1 持续集成2 软件开发模式2.1 瀑布模式2.2 敏捷开发2.2.1 迭代开发2.2.2 增量开发 3 Jenkins3.1 Jenkins安装3.1.1 导入镜像3.1.2 配置3.1.3 初始化设置 3.2 插件安装3.3 服务器环境准备3.3.1 Docker安装配置3.3.2 Git安装配置3.3.3 Maven安装配置 3.4 Jenkins工具配置…

YoloV8改进策略:卷积改进|DOConv轻量卷积,即插即用|适用各种场景

摘要 本文使用DOConv卷积&#xff0c;替换YoloV8的常规卷积&#xff0c;轻量高效&#xff0c;即插即用&#xff01;改进方法非常简单。 DO-Conv&#xff08;Depthwise Over-parameterized Convolutional Layer&#xff09;是一种深度过参数化的卷积层&#xff0c;用于提高卷…

Win10 搭建 YOLOv8 运行环境(20240423)

一、环境要求 1、Python&#xff0c;版本要求>3.7 2、PyTorch&#xff0c;版本要求>1.7。PyTorch 是一个开源的深度学习平台&#xff0c;为人工智能研究提供了一个灵活的、易于使用的工具集。YOLOv8 是基于 PyTorch 框架实现的&#xff0c;所以需要安装 PyTorch。 3、CUD…

【nginx】nginx启动显示80端口占用问题的解决方案

目录 &#x1f305;1. 问题描述 &#x1f30a;2. 解决方案 &#x1f305;1. 问题描述 在启动nginx服务的时候显示内容如下&#xff1a; sudo systemctl status nginx 问题出现原因&#xff1a; 根据日志显示&#xff0c;Nginx 服务启动失败&#xff0c;主要原因是无法绑定…

Ultralytics YOLOv8 英伟达™ Jetson®处理器部署

系列文章目录 前言 本综合指南提供了在英伟达 Jetson设备上部署Ultralytics YOLOv8 的详细攻略。此外&#xff0c;它还展示了性能基准&#xff0c;以证明YOLOv8 在这些小巧而功能强大的设备上的性能。 备注 本指南使用Seeed Studio reComputer J4012进行测试&#xff0c;它基于…

[Vue warn]: useModel() called with prop “xxx“ which is not declared

我们在使用vue3里面的defineModel的时候可能会出现这个问题&#xff0c;原因是我们使用的 kebab-case 形式的属性名&#xff0c;我也不知道是不是vue3设定这个api的时候设置的不支持&#xff0c;我没找到相关文档&#xff0c;不过我们把 kebab-case 的形式改为 驼峰命名法 或者…

【WEB前端2024】开源元宇宙:乔布斯3D纪念馆-第9课-摆件美化

【WEB前端2024】开源元宇宙&#xff1a;乔布斯3D纪念馆-第9课-摆件美化 使用dtns.network德塔世界&#xff08;开源的智体世界引擎&#xff09;&#xff0c;策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界引擎&#…

架构师系列-MYSQL调优(七)- 索引单表优化案例

索引单表优化案例 1. 建表 创建表 插入数据 下面是一张用户通讯表的表结构信息,这张表来源于真实企业的实际项目中,有接近500万条数据. CREATE TABLE user_contacts (id INT(11) NOT NULL AUTO_INCREMENT,user_id INT(11) DEFAULT NULL COMMENT 用户标识,mobile VARCHAR(50…

李沐53_语言模型——自学笔记

语言模型 1.预测文本序列出现的概率 2.应用在做预训练模型 3.生成文本&#xff0c;给定前面几个词&#xff0c;不断生成后续文本 4.判断多个序列中哪个更常见 真实数据集的统计 《时光机器》数据集构建词表&#xff0c; 并打印前10个最常用的&#xff08;频率最高的&…

Zabbix监控系统:基础配置及部署代理服务器

目录 前言 一、自定义监控内容 1、在客户端创建自定义key 2、在服务端验证新建的监控项 3、在web界面创建自定义监控项模版 3.1 创建模版 3.2 创建应用集&#xff08;用于管理监控项&#xff09; 3.3 创建监控项 3.4 创建触发器 3.5 创建图形 3.6 将主机与模板关联…

Python | Leetcode Python题解之第43题字符串相乘

题目&#xff1a; 题解&#xff1a; class Solution:def multiply(self, num1: str, num2: str) -> str:if num1 "0" or num2 "0":return "0"m, n len(num1), len(num2)ansArr [0] * (m n)for i in range(m - 1, -1, -1):x int(num1[i…

【技术干货】润石红外额温枪方案芯片功能介绍

手持红外额温枪框图中&#xff0c;以电池采用9V为例&#xff0c;先通过一个高压LDO RS3002 把电池电压转为3V&#xff0c;供整个系统使用&#xff0c;包括为 MCU&#xff0c;背光灯&#xff0c;运放 等器件供电&#xff0c;然后再用一个低功耗LDO RS3236 从3V 降为1.5V&#…

Excel如何计算时间差

HOUR(B1-A1)&"小时 "&MINUTE(B1-A1)&"分钟 "&SECOND(B1-A1)&"秒"

10种常用的JS数组循环及其应用场景

文章的更新路线&#xff1a;JavaScript基础知识-Vue2基础知识-Vue3基础知识-TypeScript基础知识-网络基础知识-浏览器基础知识-项目优化知识-项目实战经验-前端温习题&#xff08;HTML基础知识和CSS基础知识已经更新完毕&#xff09; 正文 在JavaScript中&#xff0c;数组是一种…