传送门

题意:

思路:

对于每组查询,我们直接从$u$往上搜到$v$,复杂度$O(nq)$,显然不可取(不过这题开始的数据很弱,暴力就过了)

#include<bits/stdc++.h>
using namespace std;
int n,q;
int a[100005];
int u,v,c;
int par[100005];
vector<int> G[100005];
void dfs(int u,int v){
par[u]=v;
for(auto i:G[u]){
if(i!=v) dfs(i,u);
}
}
int cal(int u,int v,int c){
int num=0;
while(u!=v){
if(a[u]>c){
c=a[u];
num++;
}
u=par[u];
}
if(a[v]>c) num++;
return num;
}
int main(){
cin>>n>>q;
for(int i=1;i<=n;i++) cin>>a[i];
int t1,t2;
for(int i=0;i<n-1;i++){
cin>>t1>>t2;
G[t1].push_back(t2);
G[t2].push_back(t1);
}
//preprocess
dfs(1,0);
while(q--){
cin>>u>>v>>c;
cout<<cal(u,v,c)<<endl;
}
return 0;
}#include<bits/stdc++.h>
using namespace std;
int n,q;
int a[100005];
int u,v,c;
int par[100005];
vector<int> G[100005];
void dfs(int u,int v){
par[u]=v;
for(auto i:G[u]){
if(i!=v) dfs(i,u);
}
}
int cal(int u,int v,int c){
int num=0;
while(u!=v){
if(a[u]>c){
c=a[u];
num++;
}
u=par[u];
}
if(a[v]>c) num++;
return num;
}
int main(){
cin>>n>>q;
for(int i=1;i<=n;i++) cin>>a[i];
int t1,t2;
for(int i=0;i<n-1;i++){
cin>>t1>>t2;
G[t1].push_back(t2);
G[t2].push_back(t1);
}
//preprocess
dfs(1,0);
while(q--){
cin>>u>>v>>c;
cout<<cal(u,v,c)<<endl;
}
return 0;
}

离线查询

既然暴力超时的话,我们可以想到用性价比很高的树上倍增,有人说倍增的本质就是二进制拆分,想想也挺有道理的。

我们用$f[i][j]$表示从$i$往上走,能买到珠宝的第$2^j$的位置,这样很容易用倍增求出最后的答案。

显然,如果我们得出$f[i][0]$,那么其他关于节点$i$的值我可以很快通过递推得到

$$f[i][j] = f[f[i][j-1]][j-1]$$

那么对于某个节点$u$,怎么求$f[u][0]$呢?肯定不可能暴力从$u$节点遍历到根节点(假如退化成一条链复杂度会大大增加)

观察到,当$fa_u$的值大于$u$时,比 $u$大的第一个值,就是 $fa_u$;否则,就是比 $fa_u$大的第 $t$个值($t$为正整数)

而第二种情况我可以用倍增来求,说实话有点难理解为什么这样做就能求出来$f[u][0]$,不过官方给出一种理解方法:

我们的$f$数组其实是对原树进行了重建,每个点往上走$1$步都连向的它能到的第一个比他大的点

至于为什么可以用倍增找,我的一点小想法:

我们先来看暴力做法:从$fa_u$开始找,一定是先找到比$fa_u$大的节点,不满足的话继续找比当前值更大的节点,以此类推直到第$t$个点满足条件。而这个过程我们在对树进行重构后,明显可以使用倍增达到目的

之后具体过程和用倍增求$lca$一样,找到$f[u][0]$下方的点,最后往上跳一格就是$f[u][0]$

其实倍增的过程仔细想想,也有点二分的味道在里面

if(val[u]<val[fa]) f[u][0] = fa;
else{
int x = fa;
for (int i = 19; i >= 0; i--){
if (f[x][i] && val[u] >= val[f[x][i]]){
x = f[x][i];
}
f[u][0] = f[x][0];
}

还有最后一个问题,题目说“每次行程开始时,你手上有价值为 $c$ 的珠宝”这个限制怎么办?很简单,在 $u $点的下方接一个权值为 $c$ 的点,然后从这个点开始往上走就可以了

问题就变成了,从$u$走到自己上方深度不小于$dep[v]$的点需要经过多少个点

关于倍增的一点看法:

通常我们要求 有指定要求的数,但是往往直接遍历求或者全部存储下来都不行通的,前者会超时后者会爆空间,所以一种折中的方法出现了——倍增。

我们只知道第$2^i$个点的情况,所以具体怎么知道哪个点是我们要找的呢?

通常这些点的信息都是有序的,比如说深度,那么我们可以想到以指定要求为限制进行二分

或者你从二进制的角度理解,假如第$t$个数就是我们要找的数,那么$t$可以拆分成二进制,既然我们知道每一位的信息,那么我们从高位往低位取,直到逼近我们要求的那个数

在线查询

并不是所有题目都会允许你离线查询,有的可能会要求强制在线,我们来看下在线的做法


Reference:

https://ac.nowcoder.com/discuss/395376?tdsourcetag=s_pctim_aiomsg

https://blog.nowcoder.net/n/970115deac7942b3a451a5f12630fb7c

https://blog.nowcoder.net/n/c6fd1e0583614363a2fc7b7f5fc6945b

https://blog.nowcoder.net/n/b6baecca0a36491c8d36671923477fff

https://blog.nowcoder.net/n/8528cf017ee148a1b98e994cd110335a

https://ac.nowcoder.com/acm/contest/view-submission?submissionId=43275876

[NC13331]城市网络的更多相关文章

  1. LOJ #6192. 「美团 CodeM 复赛」城市网络 (树上倍增)

    #6192. 「美团 CodeM 复赛」城市网络 内存限制:64 MiB 时间限制:500 ms 标准输入输出   题目描述 有一个树状的城市网络(即 nnn 个城市由 n−1n-1n−1 条道路连接 ...

  2. LibreOJ #6192. 「美团 CodeM 复赛」城市网络

    #6192. 「美团 CodeM 复赛」城市网络 内存限制:64 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: sqc 提交提交记录统计讨论测试数据   题目描 ...

  3. 美团 CodeM 复赛」城市网络

    美团 CodeM 复赛」城市网络 内存限制:64 MiB时间限制:500 ms标准输入输出 题目描述 有一个树状的城市网络(即 nnn 个城市由 n−1n-1n−1 条道路连接的连通图),首都为 11 ...

  4. LOJ 6192 城市网络(树上倍增)

    LOJ #6192. 「美团 CodeM 复赛」城市网络(链接) 一棵以 $ 1 $ 号节点为根的树,每个点有一个权值,有 $ q $ 个询问,每次从 $ x $ 点开始往某个祖先 $ y $ 走,初 ...

  5. 「美团 CodeM 复赛」城市网络

    题目链接 题意分析 首先 \([u,v]\)在树上是一条深度递增的链 那么我们可以使用倍增找 \(x\)的祖先当中深度最大的值大于\(x\)的点 然后维护一个\(pre\) 重新建树 这样从\(x\) ...

  6. Mesh无线网络的定义与WiFi的区别

    Mesh无线网络的定义与WiFi的区别 无线Mesh网络(无线网状网络)也称为「多跳(multi-hop)」网络,它是一种与传统无线网络完全不同的新型无线网络技术.无线网状网是一种基于多跳路由,对等网 ...

  7. Java网络编程和NIO详解开篇:Java网络编程基础

    Java网络编程和NIO详解开篇:Java网络编程基础 计算机网络编程基础 转自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我们是幸运的,因为 ...

  8. 001使用smokeping监控idc机房网络质量情况

    最近工作比较忙,也没有时间写博客,看到好友芮峰云最近一直在写博客,所以也手痒了,就先把之前的一些积累下来的文章分享给大家. 本文是介绍如何的使用smokeping来监控idc机房的网络质量情况,从监控 ...

  9. 借助Python来实现的定量城市研究

    一.数据处理基础 (一)数据分析的概念 城市数据分析,可以从数据分析的广义和狭义两个角度来看: 狭义的数据分析是指根据分析目的,采用对比分析.分组分析.交叉分析和回归分析等分析方法,对相关城市数据(包 ...

随机推荐

  1. Hive表的基本操作

    目录 1. 创建表 2. 拷贝表 3. 查看表结构 4. 删除表 5. 修改表 5.1 表重命名 5.2 增.修.删分区 5.3 修改列信息 5.4 增加列 5.5 删除列 5.6 修改表的属性 1. ...

  2. idea多模块启动

    2018版本的idea 原文链接http://zhhll.icu/2020/04/07/idea/idea%E4%B9%8B%E5%A4%9A%E6%A8%A1%E5%9D%97%E5%90%AF%E ...

  3. PHP将数据集转换成树状结构

    /** * 把返回的数据集转换成Tree * @param array $list 要转换的数据集 * @param string $pid parent标记字段 * @param string $l ...

  4. 【Java基础】网络编程

    网络编程 网络编程概述 网络编程的目的:直接或简洁地通过网络协议与其他计算机实现数据交换,进行通讯. 网络编程的两个主要问题: 如果准确地定位网络上一台或多台主机,并定位主机上的特定应用: 找到主机后 ...

  5. logback为不同的包或类指定输出日志文件

    对日志分割的常见需求是,需要按不同的等级进行输出,这个的配置方式类似如下,在appender节点内添加内容 <appender name="FILE-INFO" class= ...

  6. (一)React Ant Design Pro + .Net5 WebApi:先搞定服务器,顺手装个Nginx

    腾讯云搞定服务器,具体过程就不赘述了,文档都有,咨询客服或者自行百度,体验一下过程. 一. 服务器 1. 云服务器 cvm 1核2G centos8.0 2. 域名注册 www.homejok.com ...

  7. 【Vue】Vue开发环境搭建

    Vue前置学习环境 文章目录 Vue前置学习环境 IDE Node.js 调试环境 工程环境 小结 IDE WebStorm 官网下载:https://www.jetbrains.com/websto ...

  8. 【Spring】Spring的事务管理 - 1、Spring事务管理概述(数据库事务、Spring事务管理的核心接口)

    Spring事务管理概述 文章目录 Spring事务管理概述 数据库事务 什么是Spring的事务管理? Spring对事务管理的支持 Spring事务管理的核心接口 Platform Transac ...

  9. ps 2020 下载

    一款极具实用价值的作图软件--ps,由于正版价格昂贵,所以这里分享破解版的资源.b话少说,下面是下载链接和安装步骤: 下载链接: 百度网盘链接:https://pan.baidu.com/s/1XPf ...

  10. ctfhub技能树—sql注入—布尔盲注

    打开靶机 查看页面信息 开始试验,查看返回信息 此题存在一个问题,如果没有数据,也是返回query_success 如此一来,就无法使用and组合进行注入,在看了其他大佬的解题过程后,知道了可以使用& ...