FBCHEF
这道题比较有意思。
题目中贡献最多影响到距离一个节点为log的节点。
题目要修改深度相同且在某个子树的节点。可以考虑bfs序+线段树。
对一段深度相同且在某个子树的节点,他们在bfs序上是连续的,可以修改。
考虑从一个节点x向上跳修改。
先把子树的所有距离x不超过1且在子树的节点的值−=w,把y的子树内距离y不超过2且在子树的节点的值−=w/2....
再设一个值y=fax。把y的子树内距离y不超过1且在子树的节点的值−=w/2,把y的子树内距离y不超过2且在子树的节点的值−=w/4....
但是这里算重了,要把x子树的距离x不超过1且在子树的节点的值+=w/4,把y的子树内距离y不超过2且在子树的节点的值−=w/8....
这可以使用线段树简单实现。
在统计答案时,维护区间min值,暴力递归\min<0的部分。这些点破产了。
使用树状数组+dfs序统计某个点子树的破产点的个数,即可回答询问。
这里的复杂度是\min<0的节点形成的虚树大小。最坏情况是节点数*\log_2n。不是瓶颈。
所以我们可以在\log_2^2V*\log_2n的时间复杂度求出了答案。
标算的时间复杂度就是这个。
然而有更加优秀的做法。
我们的线段树可以解决对一段连续节点的区间+和区间查询。
但是我们的问题更弱,只需要单点查询,对子树距离d的点修改即可。
考虑每个点对另外的点的贡献。设f_{i,j}表示i节点对子树距离为j的点的贡献。
考虑上面使用线段树修改的过程。
我们需要对一个节点x距离=k的点-=va,则在数组上f_{x,k}-=va。
但是有些贡献算重了,要加回去。也可以在f上简单更新。
查询一个点x就是跳它的祖先z,设dis(x,z)=t,则答案+=f_{z,t}
这样子,修改时间复杂度降低到\log_2^2n。
如果我们求出每个点破产的时间,那么通过树状数组就能得到答案。
求出每个点破产的时间可以整体二分。有一种特殊的整体二分。
把所有询问一起二分。处理出所有的询问的终点值md。
把md排序,从小到大处理md。
整体二分时候按照md排序后扫描线。
使用vector。g_{x,,i}是一个二元组表,是可持久化的。g_{x,po,i,0/1}表示x距离i的点在g_{x,po,i,0}时间后,g_{x,po+1,i,0}时间前的值是g_{x,po+1,i,1}
可以简单使用前缀和处理。
在扫描线的时候,设p_{x}表示x节点的移动到了哪一个版本。
扫描线时移动p即可。
分析复杂度。
由于g_{x,i}长度的和是n\log_2的,每个元素是个长度为\log_2V的数组。所以p_x在一个扫描线最多移动\log_2V次。总次数n\log_2V
我们需要访问某个点的父亲的值,而最多访问\log_2n个,一次访问由于p已经移动好,所以访问时间复杂度是n\log_2的,做一次扫描线时间复杂度是n\log_2的
所以借助扫描线和可持久化,我们在O(n\log_2^2)的时间复杂度解决了该问题。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 【非技术】说说2024年我都干了些啥