P3258 [JLOI2014] 松鼠的新家

题目描述

松鼠的新家是一棵树,前几天刚刚装修了新家,新家有 n n n 个房间,并且有 n − 1 n-1 n1 根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在“树”上。

松鼠想邀请小熊维尼前来参观,并且还指定一份参观指南,他希望维尼能够按照他的指南顺序,先去 a 1 a_1 a1,再去 a 2 a_2 a2,……,最后到 a n a_n an,去参观新家。可是这样会导致重复走很多房间,懒惰的维尼不停地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。

维尼是个馋家伙,立马就答应了。现在松鼠希望知道为了保证维尼有糖果吃,他需要在每一个房间各放至少多少个糖果。

因为松鼠参观指南上的最后一个房间 a n a_n an 是餐厅,餐厅里他准备了丰盛的大餐,所以当维尼在参观的最后到达餐厅时就不需要再拿糖果吃了。

输入格式

第一行一个正整数 n n n,表示房间个数第二行 n n n 个正整数,依次描述 a 1 , a 2 , ⋯ , a n a_1, a_2,\cdots,a_n a1,a2,,an

接下来 n − 1 n-1 n1 行,每行两个正整数 x , y x,y x,y,表示标号 x x x y y y 的两个房间之间有树枝相连。

输出格式

一共 n n n 行,第 i i i 行输出标号为 i i i 的房间至少需要放多少个糖果,才能让维尼有糖果吃。

输入输出样例 #1

输入 #1

5
1 4 5 3 2
1 2
2 4
2 3
4 5

输出 #1

1
2
1
2
1

说明/提示

对于全部的数据,$2 \le n \le 3 \time算法思路

树结构构建:

使用邻接表存储树结构(add函数)。
节点数 n n n,访问序列存储在vis数组。
预处理阶段:

DFS遍历(dfs1函数):从根节点(设为1)出发,计算每个节点的深度 d e de de和直接父节点 f a [ i ] [ 0 ] fa[i][0] fa[i][0]

倍增预处理:计算每个节点的 2 j 2^j 2j级祖先,用于LCA查询: f a [ i ] [ j ] = f a [ f a [ i ] [ j − 1 ] ] [ j − 1 ] ( 1 ≤ j ≤ 20 ) fa[i][j] = fa[fa[i][j-1]][j-1] \quad (1 \leq j \leq 20) fa[i][j]=fa[fa[i][j1]][j1](1j20)

对数预处理:lg数组满足 2 lg [ k ] − 1 ≤ k < 2 lg [ k ] 2^{\text{lg}[k]-1} \leq k < 2^{\text{lg}[k]} 2lg[k]1k<2lg[k],用于LCA跳跃优化。

LCA计算(lca函数):

调整节点深度:若 d e [ a ] < d e [ b ] de[a] < de[b] de[a]<de[b],交换 a , b a,b a,b
将较深节点上跳到与较浅节点同一深度:
a = f a [ a ] [ lg [ d e [ a ] − d e [ b ] ] − 1 ] a = fa[a][\text{lg}[de[a]-de[b]]-1] a=fa[a][lg[de[a]de[b]]1]
若此时 a = b a=b a=b,返回 a a a;否则同步上跳至LCA的子节点: a = f a [ a ] [ j ] , b = f a [ b ] [ j ] ( j 从大到小枚举 ) a = fa[a][j], \ b = fa[b][j] \quad (j \text{从大到小枚举}) a=fa[a][j], b=fa[b][j](j从大到小枚举)

最终LCA为 f a [ a ] [ 0 ] fa[a][0] fa[a][0]

路径标记与调整:

初始化:a[vis[1]] = 1。
遍历访问序列( i i i从2到 n n n):
对相邻节点对 ( v i s [ i − 1 ] , v i s [ i ] ) (vis[i-1], vis[i]) (vis[i1],vis[i])
差分标记:b[vis[i-1]]++, b[vis[i]]++。
计算LCA(设为 j s js js):b[js]–, b[fa[js][0]]–。
调整:a[vis[i-1]]–。
序列结束:a[vis[n]]–。
差分数组累加(dfs2函数):

从叶子向根DFS,将子节点的 b b b值累加到父节点: b [ k ] = b [ k ] + ∑ 子节点 t b [ t ] b[k] = b[k] + \sum_{\text{子节点}t} b[t] b[k]=b[k]+子节点tb[t]

最终答案:

对每个节点 i i i,输出 a [ i ] + b [ i ] a[i] + b[i] a[i]+b[i]
复杂度分析
时间:
DFS遍历: O ( n ) O(n) O(n)
倍增预处理: O ( n log ⁡ n ) O(n \log n) O(nlogn)
n − 1 n-1 n1次LCA查询: O ( n log ⁡ n ) O(n \log n) O(nlogn)
差分累加: O ( n ) O(n) O(n)
总时间复杂度: O ( n log ⁡ n ) O(n \log n) O(nlogn)
空间: O ( n log ⁡ n ) O(n \log n) O(nlogn)(存储祖先数组)s 10^5$, 1 ≤ a i ≤ n 1 \le a_i \le n 1ain

详细代码

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+5;
int h[N],fa[N][25];
int vis[N],lg[N],de[N];
int a[N],b[N];
int m,n,i,j,x,y,tot;
struct node{int w,to,ne;
}wc[N*2];
void add(int a,int b)
{tot++;wc[tot].w=a;wc[tot].to=b;wc[tot].ne=h[a];h[a]=tot;
}
void dfs1(int k)
{int s=h[k];while(s!=0){int t=wc[s].to;if(t!=fa[k][0]){fa[t][0]=k;de[t]=de[k]+1;dfs1(t);} s=wc[s].ne;}
}
int lca(int a,int b)
{if(de[a]<de[b]){int t=a;a=b;b=t;}while(de[a]!=de[b]){int k=lg[de[a]-de[b]]-1;a=fa[a][k];}if(a==b) return a;else{for(j=lg[de[a]]-1;j>=0;j--){if(fa[a][j]!=fa[b][j]){a=fa[a][j];b=fa[b][j];}}}return fa[a][0];
}
void dfs2(int k)
{int s=h[k];while(s!=0){int t=wc[s].to;if(t!=fa[k][0]){dfs2(t);b[k]+=b[t];}s=wc[s].ne;}
}
int main()
{ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n;for(i=1;i<=n;i++)cin>>vis[i]; for(i=1;i<=n-1;i++){cin>>x>>y;add(x,y);add(y,x);}dfs1(1);for(j=1;j<=20;j++)for(i=1;i<=n;i++)fa[i][j]=fa[fa[i][j-1]][j-1];for(i=1;i<=n;i++)lg[i]=lg[i-1]+(1<<lg[i-1]==i?1:0);a[vis[1]]++;for(i=2;i<=n;i++){int js=lca(vis[i],vis[i-1]);b[vis[i]]++;b[vis[i-1]]++;b[js]--;b[fa[js][0]]--;a[vis[i-1]]--;}a[vis[n]]--;dfs2(1);for(i=1;i<=n;i++)cout<<a[i]+b[i]<<endl;return 0;
}

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

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

相关文章

基于openfeign拦截器RequestInterceptor实现的微服务之间的夹带转发

需求&#xff1a; trade服务需要在下单后清空购物车 分析&#xff1a; 显然&#xff0c;清空购物车需要调用cart服务&#xff0c;也就是这个功能的实现涉及到了微服务之间的转发。 其次&#xff0c;清空购车还需要userId&#xff0c;所以需要使用RequestInterceptor来实现夹…

w~深度学习~合集9

我自己的原文哦~ https://blog.51cto.com/whaosoft/14010384 #UPSCALE 这里设计了一个通用算法UPSCALE&#xff0c;可以剪枝具有任意剪枝模式的模型。通过消除约束&#xff0c;UPSCALE将ImageNet精度提高2.1个点。 paper地址&#xff1a;https://arxiv.org/pdf/2307.08…

python如何删除xml中的w:ascii属性

可以使用Python的xml.etree.ElementTree模块通过以下步骤删除XML中的w:ascii属性&#xff1a; import xml.etree.ElementTree as ET# 原始XML片段&#xff08;需包含命名空间声明&#xff09; xml_str <w:rPr xmlns:w"http://schemas.openxmlformats.org/wordproces…

【React】React CSS 样式设置全攻略

在 React 中设置 CSS 样式主要有以下几种方式&#xff0c;各有适用场景&#xff1a; 1. 内联样式 (Inline Styles) 直接在 JSX 元素中使用 style 属性&#xff0c;值为 JavaScript 对象&#xff08;使用驼峰命名法&#xff09; function Component() {return (<div style…

JS红宝书笔记 8.2 创建对象

虽然使用Object构造函数或对象字面量可以方便地创建对象&#xff0c;但这些方式有明显不足&#xff1a;创建具有同样接口的多个对象需要重复编写很多代码 工厂模式可以用不同的参数多次调用函数&#xff0c;每次都会返回一个新对象&#xff0c;这种模式虽然可以解决创建多个类…

高通camx hal进程dump日志分析三:Pipeline DumpDebugInfo原理分析

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、问题背景 二、DumpDebugInfo原理 2.1:我们分析下代码 2.2 :Pipeline Dump debug info 2.3 :dump Metadata Pending Node信息 2.4 :Dump Metadata Pool Debug信息 2.5 :No…

【数据结构】_二叉树基础OJ

目录 1. 单值二叉树 1.1 题目链接与描述 1.2 解题思路 1.3 程序 2. 相同的树 2.1 题目链接与描述 2.2 解题思路 2.3 程序 3. 对称二叉树 3.1 题目链接与描述 3.2 解题思路 3.3 程序 1. 单值二叉树 1.1 题目链接与描述 题目链接&#xff1a; 965. 单值二叉树 - 力…

软件工程画图题

目录 1.大纲 2.数据流图 3.程序流图 4.流图 5.ER图 6.层次图 7.结构图 8.盒图 9.状态转换图 10.类图 11.用例图 12.活动图 13.判定表和判定树 14.基本路径测试过程(白盒测试) 15.等价类划分(黑盒测试) 1.大纲 (1).数据流图 (2).程序流图 (3).流图 (4).ER图…

H7-TOOL自制Flash读写保护算法系列,为华大电子CIU32F003制作使能和解除算法,支持在线烧录和脱机烧录使用2025-06-20

说明&#xff1a; 很多IC厂家仅发布了内部Flash算法文件&#xff0c;并没有提供读写保护算法文件&#xff0c;也就是选项字节算法文件&#xff0c;需要我们制作。 实际上当前已经发布的TOOL版本&#xff0c;已经自制很多了&#xff0c;比如已经支持的兆易创新大部分型号&…

go channel用法

介绍 channel 在 Go 中是一种专门用来在 goroutine 之间传递数据的类型安全的管道。 你可以把它理解成&#xff1a; 多个 goroutine 之间的**“传话筒”**&#xff0c;谁往通道里塞东西&#xff0c;另一个 goroutine 就能接收到。 Go 语言采用 CSP&#xff08;Communicatin…

openLayers切换基于高德、天地图切换矢量、影像、地形图层

1、需要先加载好地图&#xff0c;具体点此链接 openLayers添加天地图WMTS、XYZ瓦片服务图层、高德地图XYZ瓦片服务图层-CSDN博客文章浏览阅读31次。本文介绍了基于OpenLayers的地图交互功能实现&#xff0c;主要包括以下内容&#xff1a; 地图初始化&#xff1a;支持天地图XYZ…

springMVC-15 异常处理

异常处理-基本介绍 基本介绍 1.Spring MVC通过HandlerExceptionResolver处理程序的异常&#xff0c;包括Handler映射、数据绑定以及目标方法执行时发生的异常。 2.主要处理Handler中用ExceptionHandler注解定义的方法。 3.ExceptionHandlerMethodResolver内部若找不到Excepti…

视频汇聚EasyCVR平台v3.7.2发布:新增全局搜索、播放器默认解码方式等4大功能

EasyCVR视频汇聚平台带着全新的v3.7.2版本重磅登场&#xff01;此次升级&#xff0c;绝非简单的功能堆砌&#xff0c;而是从用户体验、操作效率以及系统性能等多维度进行的深度优化与革新&#xff0c;旨在为大家带来更加强大、稳定且高效的视频监控管理体验。 一、全局功能搜索…

三、kubectl使用详解

三、kubectl使用详解 文章目录 三、kubectl使用详解1、常用基础命令1.1 Kubectl命令格式1.2 查询一个资源1.3 创建一个资源1.4 修改一个资源1.5 删除一个资源1.6 其他 2、K8s隔离机制Namespace&#xff08;命名空间作用及使用&#xff09;2.1 什么是命名空间2.2 命名空间主要作…

JVM内存模型详解

JVM内存模型详解 Java虚拟机(JVM)内存模型是理解Java程序运行机制的核心&#xff0c;它定义了程序运行时数据的组织方式和访问规则。与Java内存模型(JMM)关注并发不同&#xff0c;JVM内存模型主要描述运行时数据区的结构和功能。 一、JVM内存模型概述 JVM内存模型将运行时数…

《对话式 AI 白皮书》共创者招募

在 AI Agent 技术不断演变的当下&#xff0c;共创一本不断演变的对话式 AI 白皮书&#xff0c;共同探索人机对话的新纪元。无论你是开发者、技术专家、生态伙伴还是创业者&#xff0c;都期待你的加入。 项目地址&#xff1a;https://github.com/RTE-Dev/book_era_convoai/ 在…

Flux功能介绍,完整使用示例,与Mono对比

以下是关于Reactor框架中Flux与Mono的功能介绍、使用示例及对比分析&#xff1a; Flux功能介绍 核心定义 Flux是Reactor库中的核心接口&#xff0c;表示一个异步的、包含零到多个元素的序列&#xff08;类似流式数据处理&#xff09;[3][4][7]。它可以处理无限长度的数据流&am…

Git使用基本指南

一、Git 基础配置 首先需要配置用户信息&#xff0c;让 Git 知道你是谁&#xff1a; git config --global user.name "你的名字" git config --global user.email "你的邮箱example.com" 如果需要查看配置信息&#xff0c;可以使用&#xff1a; git co…

【入门】【例17.3】 内功逼毒

| 时间限制&#xff1a;C/C 1000MS&#xff0c;其他语言 2000MS 内存限制&#xff1a;C/C 64MB&#xff0c;其他语言 128MB 难度&#xff1a;中等 分数&#xff1a;100 OI排行榜得分&#xff1a;12(0.1分数2难度) 出题人&#xff1a;root | 描述 黄蓉中了毒&#xff0c;在 t 时…

苹果芯片macOS安装版Homebrew(亲测)

在Linux服务器上安装一个软件常用yum&#xff0c;apt、dnf命令&#xff0c;同样macOS可以使用brew命令来安装软件。 brew会自动帮你下载、解压、安装和配置&#xff0c;更重要的是&#xff1a;它还会自动处理好软件之间的依赖关系&#xff0c;它将所有软件都安装在独立的统一目…