首页 > 其他分享 >南外集训 2024.2.14 T3

南外集训 2024.2.14 T3

时间:2024-02-14 18:55:05浏览次数:27  
标签:影子 2024.2 子树 T3 叶子 南外 卡常 转移 关键点

总觉得做过,但是就是想不起来在哪里做到的。

有两个人一开始在一棵树的根节点,每秒钟两人都可以向下走一条边。任意时刻,一个人可以瞬间移动到另一个人所在的点上。求遍历树上的所有点所需最短时间。

\(1\le n\le 5\times 10^6\)

注意到我们只需要访问所有的叶子。我们把其中一个人叫人,另一个叫影子。

一个错误的想法:考虑一种状态设计:两个人同时在 \(u\),且 \(u\) 子树外的所有点都被访问过,\(u\) 子树内只有 \(u\) 呗访问过。那么此时的策略(似乎)应该是留下一棵子树不动它,然后影子不停地下去处理其他子树里的叶子,直到只剩一个最深的,然后人不停往被保留的子树走,直到第一个有分叉的位置,同时影子向最后一个叶子走。两个人都走到目的地以后,影子瞬间移动回到人,转移到子问题。

这个想法是错误的,而且实际上是很不自然的:假设当前节点只有两个儿子,其中各有一个非常深的叶子,以及一系列很浅的叶子,那么正确的策略是保留两个最深的叶子,人一直不动,影子把所有浅叶子处理掉以后两人同时往两个深叶子走。而我们上面的策略实际上限制了进入一棵子树的时候必须要清理掉所有外面的叶子,只有子树上面的一小段单个儿子的链可以和外面的并行处理,而这是非常不自然的,并不能真正起到并行减少时间的效果,因为很容易通过在每个点旁边挂一些浅叶子来消除掉这种单个儿子的链,而直觉告诉我们最优解的策略不应该受此影响。

我们重新考虑整个问题。事实上我们并不是在一棵子树一棵子树地解决问题,而是通过每次确定一个特殊的子树并进入的过程,确定了一个特殊的根-叶子链,具体地也就是上面过程中人(而不是影子)所走的路径。每个不在这条链上的叶子都需要由影子在某个时刻出发去清理掉。假设已经选定了这个路径,我们可以将最小化总时间转化为最小化人等待影子的时间,进一步地,如果影子等待人,那么我们可以强制将它传送回来跟着人走。这样,我们只需要决定路径上的一系列关键点,在这些关键点,人等待影子清理一些叶子。影子每次会清理一个叶子,回到人,再清理,……,直到所有从这个关键点出发的叶子只剩最后一个(最优解中一定是最深的那个),此时人就开始向下走,且影子清理完这个叶子之前,人必须已经走到下一个关键点。那么注意到此时总时间实际上就是影子清理叶子的总时间,即所有被清理的叶子的深度和减去关键点的(带权)深度和,因为人永远在等待影子。

下面考虑一个 \(\Theta(n^2)\) 的 DP。设 \(f_u\) 表示走到点 \(u\) 时,最少已经花费的时间,转移直接在 \(u\) 到根的链上枚举上一个关键点 \(v\),设 \(S_x\) 表示 \(x\) 子树内所有叶子的集合。\(sum(S_x)\) 表示 \(S_x\) 的深度和;\(mxd(S_x)\) 表示 \(S_x\) 的深度最大值,则转移合法当且仅当:\(mxd(S_v\backslash S_u) - dep_v \ge dep_u - dep_v\),转移为 \(f_v + sum(S_v\backslash S_u) - |S_v\backslash S_u|\cdot dep_v \to f_u\)。此外特判一下父节点只有一个儿子可以直接转移过来。

由于 \(S_v\backslash S_u\) 可以拆分成 \(path(v,u)\backslash\{v\}\) 的“兄弟子树信息”的并,结合上面的式子我们发现,对于一个 \(u\),根到它的链上的一个前缀都是合法的。又注意到,在合法的前提下,转移的时间越晚越好。这是因为在某个合法解中,不影响合法性地插入一个关键点,会使得链外的叶子更容易匹配到离它更近的关键点,从而使答案更优。除此之外,如果在 \(u\) 可以从 \(v\) 转移过来,那么 \(path(v, u)\) 上的每个点都可以从 \(v\) 转移过来。所以我们只关心最后一个合法转移位置。利用重链剖分进行寻找及转移,容易获得 \(\Theta(n\log n)\) 做法。

注意到在上面的问题中我们使用了重链剖分,而转移合法性是深度相关信息,这简直倒反天罡。把重链剖分换成长链剖分,发现如果我们在向上寻找的过程中跳了长链,此时走到的第一个位置一定已经是合法转移了,于是不用再往上考虑。没跳长链的部分直接用单调栈。复杂度 \(\Theta(n)\)。

我草,卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼。

标签:影子,2024.2,子树,T3,叶子,南外,卡常,转移,关键点
From: https://www.cnblogs.com/kyeecccccc/p/18015427

相关文章

  • #13 2024.2.8
    大概能从#12和#13的日期看出,博主到底摆了多久。博主没救了呜呜呜wuwuwuwuuwu。hbxql。568.xsy5348栞569.xsy5349Metropolis570.xsy5350bus571.xsy5351重排572.xsy5352黄焖鸡573.xsy5353Utopiosphere574.loj3706「ZJOI2022」树updateon2024.2.11:康......
  • 2024.2.8&2024.2.9
    1.重写是子类对父类的允许访问的方法的实现过程进行重新编写,返回值和形参都不改变。即外科不变,核心重写。重写的好处在于,子类可以根据需求,定义特定于自己的行为。也就是说子类可以根据需求实现父类的方法。重写方法不能抛出新的检查异常或者比被重写方法更加宽泛的异常。例如:父......
  • 洛谷P10136 暨 USACOJan2024S T3 题解
    题意简述原题已经很简了,没有什么简述的必要了。思维路径请注意本题解可以保证正确性但不保证如果有极端的Hack数据能够通过。拿到这道题上来的暴力想必是很容易的,即枚举每个\(L\)判断是否合法。接着我们就考虑优化,减少需要枚举的\(L\)的量。题目中要求余数最多有\(3\)......
  • 【Spring】SpringBoot3+SpringBatch5.xの構築
    ■概要  ■POMのXMLの設定<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation=&qu......
  • (C语言)代码学习||2024.2.6||题目是codewars上的【 IP Validation】
    C语言#sscanf#代码学习#codewars题目链接:IPValidation|Codewars代码如下:#include<stdio.h>intis_valid_ip(constchar*addr){unsignedn[4],i,nc;//Mustbe4integersseparatedbydots:if(sscanf(addr,"%d.%d.%d.%d%n",&n[0],&n......
  • 2024.2.6每日一题
    LeetCode魔塔游戏LCP30.魔塔游戏-力扣(LeetCode)题目描述小扣当前位于魔塔游戏第一层,共有N个房间,编号为0~N-1。每个房间的补血道具/怪物对于血量影响记于数组nums,其中正数表示道具补血数值,即血量增加对应数值;负数表示怪物造成伤害值,即血量减少对应数值;0表示房间对血量......
  • 2024.2.6
    1.Java不支持多继承但支持多重继承2.继承的特性·子类拥有父类非private的属性、方法·子类可以拥有自己的属性和方法,即子类可以对父类进行扩展·Java的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如B类继承A类,C类继承B类,所以按照关系就......
  • 全国产T3+FPGA的SPI与I2C通信方案分享
    近年来,随着中国新基建、中国制造2025规划的持续推进,单ARM处理器越来越难胜任工业现场的功能要求,特别是如今能源电力、工业控制、智慧医疗等行业,往往更需要ARM+FPGA架构的处理器平台来实现例如多路/高速AD采集、多路网口、多路串口、多路/高速并行DI/DO、高速数据并行处理等特定......
  • (python)代码学习||2024.2.4||题目是codewars的【 All Balanced Parentheses】
    题目链接:https://www.codewars.com/kata/5426d7a2c2c7784365000783/pythondefbalanced_parens(n):'''Toconstructallthepossiblestringswithnpairsofbalancedparenthesesthisfunctionmakesuseofastackofitemswiththefoll......
  • 2024.2.5寒假每日总结27
    LeetCode跳跃游戏VI1696.跳跃游戏VI-力扣(LeetCode)题目描述给你一个下标从0开始的整数数组nums和一个整数k。一开始你在下标0处。每一步,你最多可以往前跳k步,但你不能跳出数组的边界。也就是说,你可以从下标i跳到[i+1,min(n-1,i+k)]包含两个端点的任......