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;staticclass 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);}}staticclass 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];//rhaup=new M[n+1];//haa=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) {
//			}
//		}staticclass 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());}}
}

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

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

相关文章

Rust 使用结构体组织相关联的数据

目录 结构体的定义和实例化 使用字段初始化简写语法使用结构体更新语法从其他实例创建实例使用没有命名字段的元组结构体来创建不同的类型没有任何字段的类单元结构体结构体示例程序 通过派生 trait 增加实用功能方法语法 定义方法带有更多参数的方法关联函数多个 impl 块本文有…

大厂常见算法50题-反转链表

专栏持续更新50道算法题&#xff0c;都是大厂高频算法题&#xff0c;建议关注。 文章目录 解法参考链接题目解法一 双指针解法二 递归解法三 妖魔化的双指针总结 解法参考链接 题目 解法一 双指针 定义两个指针&#xff1a; pre 和 cur。pre 在前 cur 在后。每次让 pre的 nex…

Day4 商品管理

Day4 商品管理 这里会总结构建项目过程中遇到的问题&#xff0c;以及一些个人思考&#xff01;&#xff01; 学习方法&#xff1a; 1 github源码 文档 官网 2 内容复现 &#xff0c;实际操作 项目源码同步更新到github 欢迎大家star~ 后期会更新并上传前端项目 编写品牌服务 …

在线预约订房酒店小程序源码系统 带完整的安装代码包以及=安装部署教程

传统的酒店预订方式往往依赖于电话、邮件或者到店咨询&#xff0c;这种方式不仅效率低下&#xff0c;而且容易造成信息不准确、沟通不畅等问题。随着智能手机的普及和移动互联网的发展&#xff0c;用户对于随时随地、方便快捷地进行酒店预订的需求日益增强。小编给大家分享一款…

[MySQL]运算符

1. 算术运算符 (1). 算术运算符 : , -, *, / 或 DIV, % 或MOD. (2). 例 : (3). 注 : DUAL是伪表.可以看到4/2结果为小数&#xff0c;并不会截断小数部分.(可能与其他语言不同&#xff0c;比如java中&#xff0c;两个操作数如果是整数&#xff0c;则计算得到的也是整数&…

羊大师:夏季羊奶的好处有哪些?

夏季羊奶的好处主要包括以下几点 1.增强免疫力&#xff1a;羊奶中的钙元素丰富&#xff0c;能有效为身体补充营养物质&#xff0c;增强自身的免疫能力。羊奶还富含上皮细胞生长因子&#xff08;EGF&#xff09;&#xff0c;对人体鼻腔、咽喉、血管、肠胃等黏膜有良好的修复作用…

Qt 跨平台开发的一丢丢总结

Qt 跨平台开发 文章目录 Qt 跨平台开发摘要第一 \ & /第二 神奇{不能换行显示第三 预处理宏 关键字&#xff1a; Qt、 win、 linux、 lib、 MSVC 摘要 最近一直在琢磨Qt跨平台开发的问题&#xff0c;缘由有以下几个&#xff0c; 首先第一个&#xff0c;我们目前开发…

几种比Serv-u更好满足企业的替代工具方案

很多目前企业面临的挑战是如何在保障数据安全的同时&#xff0c;提高文件传输的效率。传统的FTP服务器&#xff0c;如Serv-U&#xff0c;虽然长期服务于文件共享与传输&#xff0c;但在新兴需求面前显得力不从心。 于是企业开始寻求更先进的解决方案以应对跨地域、大容量的文件…

Vue 3中的ref和toRefs:响应式状态管理利器

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【图说】VMware Ubuntu22.04 详细安装教程

前言 无论是从事 Linux 开发工作&#xff0c;还是希望电脑运行双系统&#xff0c;VMware 虚拟机都是我们日常工作不可或缺的工具。本章将会重点介绍 VMware 安装流程&#xff0c;以及在 VMware 上如何运行、使用 Ubuntu22.04 系统。 一、VMware 下载安装 1.1 VMware 官网下载…

【Hello算法】 > 第 3 关 >栈与队列

数据结构 之 数组与链表 1 栈 / 栈的常见操作、实现、应用2 队列 /队列的常见操作、实现、应用3 双向队列4 Tips ———————————————————————————————————————————————————————————- ————————————————…

鼠标坐标传感器FCT3065

参考链接 如何优雅的DIY鼠标&#xff1f; | 技术文章 | 汇顶科技开发者社区 (goodix.com)https://developers.goodix.com/zh/bbs/blog_detail/bebdd04ccdfc4f7682ab27a8e77a14ad GitHub - VineetSukhthanker/FCT3065-XY_MouseSensor: Interface FCT3065-XY optical mouse sen…

面试算法准备:动态规划

这里写自定义目录标题 1 理论2 例题2.1 斐波那契数列&#xff08;什么是重叠子问题&#xff09;2.1.1 带备忘录的递归解法 2.2 零钱兑换&#xff08;讲解最优子结构&#xff09;2.3 最长递增子序列&#xff08;讲解如何求解状态转移方程&#xff09;2.4 俄罗斯套娃信封问题&…

Vue3、 Vue2 Diff算法比较

Vue2 Diff算法 源码位置:src/core/vdom/patch.ts 源码所在函数:updateChildren() 源码讲解: 有新旧两个节点数组:oldCh和newCh; 有下面几个变量: oldStartIdx 初始值=0 oldStartVnode 初始值=oldCh[0] oldEndIdx 初始值=oldCh.length - 1 oldEndVnode 初始值=oldCh[ol…

鸿蒙 harmonyos 线程 并发 总结 async promise Taskpool woker(三)多线程并发 Worker

Worker Worker是与主线程并行的独立线程。创建Worker的线程称之为宿主线程&#xff0c;Worker自身的线程称之为Worker线程。创建Worker传入的url文件在Worker线程中执行&#xff0c;可以处理耗时操作但不可以直接操作UI。 Worker主要作用是为应用程序提供一个多线程的运行环境…

CTFshow-PWN-栈溢出(pwn36)

存在后门函数&#xff0c;如何利用&#xff1f; 好好好&#xff0c;终于到了这种有后门函数的了 checksec 检查一下&#xff1a; 32 位程序&#xff0c;RELRO 保护部分开启 RWX: Has RWX segments 存在可读可写可执行的段 使用 ida32 看 main 函数 跟进 ctfshow 函数…

Scala 04 —— Scala Puzzle 拓展

Scala 04 —— Scala Puzzle 拓展 文章目录 Scala 04 —— Scala Puzzle 拓展一、占位符二、模式匹配的变量和常量模式三、继承 成员声明的位置结果初始化顺序分析BMember 类BConstructor 类 四、缺省初始值与重载五、Scala的集合操作和集合类型保持一致性第一部分代码解释第二…

L3-1 夺宝大赛-2024天梯赛(内存超限解决方法)

题目 夺宝大赛的地图是一个由 nm 个方格子组成的长方形&#xff0c;主办方在地图上标明了所有障碍、以及大本营宝藏的位置。参赛的队伍一开始被随机投放在地图的各个方格里&#xff0c;同时开始向大本营进发。所有参赛队从一个方格移动到另一个无障碍的相邻方格&#xff08;“…

聊聊如何通过arthas-tunnel-server来远程管理所有需要arthas监控的应用

前言 Arthas 是一款线上监控诊断产品&#xff0c;通过全局视角实时查看应用 load、内存、gc、线程的状态信息&#xff0c;并能在不修改应用代码的情况下&#xff0c;对业务问题进行诊断&#xff0c;包括查看方法调用的出入参、异常&#xff0c;监测方法执行耗时&#xff0c;类…

Redis入门到通关之Redis实现Session共享

文章目录 ☃️前期概要☃️基于Session实现登录方案☃️现有方案存在的问题☃️Redis代替Session的业务流程❄️❄️设计key的结构❄️❄️设计key的具体细节❄️❄️整体访问流程 欢迎来到 请回答1024 的博客 &#x1f353;&#x1f353;&#x1f353;欢迎来到 请回答1024的博…