题解:CF983E NN country

news/2025/11/2 0:23:00/文章来源:https://www.cnblogs.com/CharlieCai/p/19184098

首先思考线路只有从祖先到子孙的链的情况,对于询问的两个点 \(x\)\(y\),我们肯定要先从 \(x\) 跳到它们的 LCA,再从 LCA 跳到 \(y\)。由于从 LCA 到 \(y\) 的过程和从 \(y\) 到 LCA 的过程是等价的,所以我们可以先算出每个点在经过一定数量的线路时最远能到达哪个祖先。

暴力跳肯定不行,考虑倍增,记 \(f_{x,i}\) 表示从 \(x\) 开始往上跳,经过 \(2^{i}\) 条线路时最远能跳到的点。显然在得到每条线路的两端点 \(x\)\(y\) 时我们可以更新 \(f_{x,0}\)\(f_{y,0}\)\(x\)\(y\) 的 LCA(如果 LCA 的深度更小的话)。对于链上的其它点,在输入所有线路后我们进行一次 dfs 判断每个点 \(x\) 的儿子 \(son\)\(f_{son,0}\) 能否更新 \(f_{x,0}\)。最后倍增求出整个 \(f\) 数组,询问时直接按照 \(f\) 的值计算答案即可。

接下来考虑正常情况,对于不是从祖先到子孙的链的线路,我们考虑将它拆成一条从 LCA 到 \(x\) 的链和一条从 LCA 到 \(y\) 的链,统计答案时考虑是否要经过这条线路的拐弯处,如果要就将答案减 \(1\)。考虑如何判断答案是否需要减,记询问的两个点为 \(qx\)\(qy\),记 \(qx\) 到 LCA 的链上 LCA 的儿子为 \(a\)\(qy\) 到 LCA 的链上 LCA 的儿子为 \(b\)。显然如果存在一条可以经过拐弯的线路(记两端点为 \(x\)\(y\)),那么 \(x\) 肯定在 \(a\) 的子树中,\(y\) 肯定在 \(b\) 的子树中。转换一下也就是 \(dfn_a \le dfn_x \le dfn_a+siz_a-1\)\(dfn_b \le dfn_y \le dfn_b+siz_b-1\)。这样就转化成了二维数点问题,计算答案是否大于 \(0\) 即可,如果大于那最后就要减。

#include<bits/stdc++.h>
#define MAXN 400005
#define int long long
using namespace std;
const int inf=1e18;
int id,n,m,q,head[MAXN],cnt,fa[MAXN][22],f[MAXN][22],deep[MAXN],tree[MAXN],dfn[MAXN],num,ans[MAXN],qans[MAXN],bot[MAXN];
int lb(int x){return x&(-x);
}
void add(int x,int y){for(int i=x;i<=n;i+=lb(i))tree[i]+=y;
}
int que(int x,int y){int tans=0;for(int i=y;i;i-=lb(i))tans+=tree[i];for(int i=x-1;i;i-=lb(i))tans-=tree[i];return tans;
}
struct Edge{int value,next;
}edge[MAXN];
void addedge(int u,int v){edge[++cnt].value=v;edge[cnt].next=head[u];head[u]=cnt;
}
void dfs1(int x,int father){fa[x][0]=father;deep[x]=deep[father]+1;dfn[x]=++num;;for(int i=1;i<=21;i++)fa[x][i]=fa[fa[x][i-1]][i-1];for(int i=head[x];i;i=edge[i].next){int y=edge[i].value;if(y!=father){dfs1(y,x);}}bot[x]=num;
}
int LCA(int x,int y){if(deep[x]<deep[y])swap(x,y);for(int i=21;i>=0;i--){if(deep[fa[x][i]]>=deep[y])x=fa[x][i];} if(x==y)return x;for(int i=21;i>=0;i--){if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];}return fa[x][0];
}
void dfs2(int x){for(int i=head[x];i;i=edge[i].next){int y=edge[i].value;if(y!=fa[x][0]){dfs2(y);if(!f[x][0]||(f[y][0]&&deep[f[y][0]]<deep[f[x][0]])){f[x][0]=f[y][0];}}}
}
struct Node{int x,y,k,f,id;
}p[MAXN*4];
int tcnt;
bool cmp(Node x,Node y){return x.x==y.x?x.id<y.id:x.x<y.x;
}
signed main(){
//	freopen("metro.in","r",stdin);
//	freopen("metro.out","w",stdout);scanf("%lld",&n);for(int i=2;i<=n;i++){int v;scanf("%lld",&v);addedge(i,v),addedge(v,i);}dfs1(1,0);scanf("%lld",&m);for(int i=1;i<=m;i++){int x,y;scanf("%lld%lld",&x,&y);if(dfn[x]>dfn[y])swap(x,y);int l=LCA(x,y);if(!f[x][0]||(deep[l]<deep[f[x][0]]))f[x][0]=l;if(!f[y][0]||(deep[l]<deep[f[y][0]]))f[y][0]=l;p[++tcnt]=(Node){dfn[x],dfn[y],0,0,0};}dfs2(1);for(int i=1;i<=n;i++)if(f[i][0]==i)f[i][0]=0;for(int i=1;i<=21;i++){for(int j=1;j<=n;j++){f[j][i]=f[f[j][i-1]][i-1];}}scanf("%lld",&q);for(int i=1;i<=q;i++){int x,y;scanf("%lld%lld",&x,&y);if(dfn[x]>dfn[y])swap(x,y);int l=LCA(x,y);if(x==y){ans[i]=0;continue;}for(int j=21;j>=0;j--)if(f[x][j]&&deep[f[x][j]]>deep[l])x=f[x][j],ans[i]+=(1<<j);for(int j=21;j>=0;j--)if(f[y][j]&&deep[f[y][j]]>deep[l])y=f[y][j],ans[i]+=(1<<j);if((!f[x][0]&&x!=l)||(!f[y][0]&&y!=l)){ans[i]=-1;continue;}if(l==x||l==y)ans[i]++;else{ans[i]+=2;p[++tcnt]=(Node){bot[x],bot[y],1,1,i};p[++tcnt]=(Node){dfn[x]-1,bot[y],-1,1,i};p[++tcnt]=(Node){bot[x],dfn[y]-1,-1,1,i};p[++tcnt]=(Node){dfn[x]-1,dfn[y]-1,1,1,i};}}sort(p+1,p+tcnt+1,cmp);for(int i=1;i<=tcnt;i++){if(p[i].f==0)add(p[i].y,1);else qans[p[i].id]+=que(1,p[i].y)*p[i].k;}for(int i=1;i<=q;i++){printf("%lld\n",ans[i]-(qans[i]>0));}return 0;
}

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

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

相关文章

CSP-S 2023 游记

1. 你知道吗?红绿灯倒计时的第一位的取值范围不是 0~9,而是 0~F。 半个十六进制的红绿灯。 半个有 OI 的生活。 第一次看到它,是在考完 csps2023 回家的路上,我家长确信那只是二极管失灵,但我亲眼看到它从 E,到…

软件技术基础的第二次作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/zjlg/25rjjc/homework/13541这个作业的目标 建立本地项目并关联远程仓库,熟悉程序设计的流程姓名-学号 熊宇彤-2023331200153码云仓库地址:https://gitee.com/…

补发周五日报10.31

所花时间:90min 今天主要学习内容主要是机器学习,上课没咋听 知识点总结 这个问题很关键,决策树是机器学习的基础算法,也是软件设计师考试中机器学习部分的高频考点!核心结论:决策树是一种基于 “分而治之” 思想…

CSP2025-S 游记

Day -2 早上写了教练的模拟赛,下午讲题。 晚上和 @Kevin_Mu 一起研究了神秘的dfs序求LCA,发现非常好写,同时学了ST表。 Day -1 努力的刷板子,但是头疼只写了一点点,然后把所有写过的板子看了看,把很久没写过的单…

langgraph-reflection

langgraph-reflection https://github.com/fanqingsong/langgraph-reflectionDescriptionArchitectureThis reflection agent uses two subagents:- A "main" agent, which is the agent attempting to solv…

学习日报11.2

所花时间:1h 代码量:0 搏客量:2 所学知识点:今天所学的内容是有关于中级软件设计师备考内容 关于上午题 由于所学知识点比较多,且杂乱,就简单叙述一下,大致是有关于有限自动机,一个叫状态图的认识,刚开始比较…

2025CSP-S游记

DAY -13 脱产了。正好还是运动会,到时候会有人来一起在机房。 DAY -12~-10 运动会,感觉好青春啊 hhh。这个气温也是迅速下降,好在机房还是冬暖夏凉。 DAY -9~-5 一个人在机房,但其实也还好,主要就是做同学的好题题…

获取网页logo图标(ico文件)

怎么获取网页logo图标的URL链接 第一种方法:最常用的方法(适用于90%的站点)是,直接在访问网址首页链接后加上上/favicon.ico,例如:https://www.baidu.com/favicon.ico 第二种方法:按F12,进入开发者模式。以wi…

题解:P6811 「MCOI-02」Build Battle 建筑大师

设 $f_i$ 为匹配到第 $i$ 为的序列个数,令 $last_{x,i}$ 表示从第 $i$ 为往前第一个出现 $x$ 的位置,可以得到转移 $f_i=\sum_{j=last_{a_i,i}}^{i-1}{f_j}$。最后答案即为 $\sum{f}$。 由于本题 $a$ 的特殊性,所有…

[KaibaMath]1017 关于收敛数列与其子数列之间的关系定理的证明

[KaibaMath]1017 关于收敛数列与其子数列之间的关系定理的证明收敛数列的任意子数列必收敛,且极限与原数列的极限一致。反之,若一个数列存在发散的子数列,或存在两个极限不同的子数列,则该数列必发散。下面给出收敛…

Day9综合案例一

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">…

学习日报11.1

所花时间:2h 代码量:200 所学知识点: 今日核心知识点总览 有限自动机(FA):含核心五要素(状态集合、输入符号集合等),区分 DFA 与 NFA,掌握 NFA 转 DFA 的子集构造法及字符串识别流程。 上下文无关文法:明确…

团队展示选题:KFCoder✅日常健康打卡系统

项目 内容这个作业属于哪个课程 ->点我进入课程主页这个作业要求在哪里 ->点我查看作业要求这个作业的目标 成立团队并完成选题,初步确立团队计划Github仓库链接 zhiyuxinxuan/KFCoder一、团队展示 队名:KFCod…

UE:快速创建一个地图

这里只讨论如何快速创建一个可用的标准地图,不包括世界分区地图。 先Ctrl+空格呼出内容浏览器,鼠标右击选择关卡打开窗口->环境光照混合器依次点击这些按钮就能创建一个完整的标准地图,方便又快捷。 如果要创建地…

以数据为中心的计算机视觉模型性能分析工具-FiftyOne -1

提高数据质量和了解模型的故障模式是提高模型性能的最有效方法。 FiftyOne是一个开源工具,为数据集标记和计算机视觉模型分析提供了强大的图形界面。“提高数据质量和了解模型的故障模式是提高模型性能的最有效方法。…

23 种设计模式完整指南 - C++实现详解

23 种设计模式完整指南 - C++实现详解 目录设计模式概览 创建型模式 结构型模式 行为型模式 实践应用 总结设计模式概览 设计模式是解决软件设计中常见问题的可重用方案。它们提供了经过验证的解决方案,帮助开发者编写…

[Linux] Linux创建用户流程

[Linux] Linux创建用户流程$(".postTitle2").removeClass("postTitle2").addClass("singleposttitle");目录以创建用户组和用户 mgter 为例: 以创建用户组和用户 mgter 为例: #!/bin/…

Zabbix 数据库 history_uint 表损坏修复

使用CentOS 9部署Zabbix 7.0使用一段时间后,查询历史数据时出现报错,Zabbix图形历史数据显示异常。并且Zabbix对接了Grafana,在Grafana历史图形中出现图像数据不连续的现象。Zabbix前端Top hosts by CPU untilizati…