当前位置: 首页 > news >正文

神秘推性质

同步发布于 here。

思路

神秘推式子题。

发现每个层的节点数和每个边的边权是随着深度的增加递增的,且存在公差 \(d=1\),即其是一个等差数列,这个在我们后面需要用到。

题目询问 \(u,v\) 的最短距离,我们把每个节点 \(i\) 的深度设为 \(dep_i\),令 \(dep_u \le dep_v\),考虑两种情况:

  1. \(u\)\(v\) 到节点 \(1\) 的路径上,则答案就是其中间的等差数列的和。
  2. \(u\) 不在 \(v\) 到节点 \(1\) 的路径上,其答案就是每个点到其 LCA 的权值的和,即两个等差数列的和。

发现其实判断 \(u\) 是否在 \(v\)\(1\) 的路上,还是要求 LCA 的,所以我们就想怎么求 LCA。

发现其并不完全相同于一棵树,所以我们不能求其直接的 LCA,但是,我们发现,我们可以求 \(v\)\(dep_u\) 深度时,所能到达的左右端点,可见,其中间所有的点都可以到达。

那么我们可以考虑 \(v\) 向上走走到 \(dep_u\) 时候的情况,发现若 \(u\)\(v\) 能到达的区间 \([l,r]\) 中,即 \(l \le u \le r\) 时,答案就是 \(dep_u\)\(dep_v\) 中间的边权的等差数列和,即 \(\sum_{i = dep_u} ^ {dep_{v} - 1} i\)
\(u \le l\)\(r \le u\) 时,可以发现,取最优的 LCA,同一深度的两个点就要尽可能的近,所以 \(v\) 就取 \(l\)\(r\) 即可,其 LCA 就是一个一直向左上走,一个一直向右上走,直到这俩相遇,这也是个等差数列,只举 \(u \le l\) 的情况,其和为 \(\sum_{i = \max(dep_{u} - (l-u), 1)} ^ {dep_{u} - 1} i \times 2\) 其中乘二是因为要走两个相同长度的路。

上面的等差数列式子显然,根据所给图分析即可。

现在就只剩下两个问题:如何求深度且如何求这个区间。

求深度可以思考,我们其实是要解一个形似 \(x \times (x + 1) \ge v\) 的不等式,取相等,则 \(x = \left\lceil \frac{-1+\sqrt {1 + 8v}}{2} \right\rceil\)(负根被舍了) 可以发现因为精度我们是不准的,可能需要微调,这个用 while 即可,因为我们求的是近似确切值,所以 while 次数不会很多,时间复杂度约为 \(O(1)\)

求区间,我们再次观察图,发现对于 \(v\),其向左上走变成了 \(v - dep_v\) 了,其向右上走就变成了 \(v - (dep_v - 1)\) 了。可见,其走到 \(dep_u\) 也是一个等差数列,用等差数列求和得到向左右走的长度即可。

:::warning[注意边界]
注意我们理论上求得了 \(v\) 走到 \(dep_u\) 所能到的区间,但是我们的数学计算可能会使实际的 \(l,r\) 超出那个深度的边界编号,所以我们要与其边界编号分别取最大最小。
:::

代码

现在所有问题已经解决了,注意等差数列求和的起点,终点和个数即可,代码中我默认的是 \(dep_u \ge dep_v\),注意不要搞混了。

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
ll t, u, v;
ll calc(ll l, ll r, ll d){return (r + l) * d / 2;}
int main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);cin >> t;while(t --){cin >> u >> v;if(u == v){cout << 0 << '\n';continue;}ll depu = ceil((-1 + sqrtl(1 + 8 * u)) / 2), depv = ceil((-1 + sqrtl(1 + 8 * v)) / 2), cnt = 0;while(depv * (depv + 1) / 2 < v) depv ++;while(depu * (depu + 1) / 2 < u) depu ++;//微调深度 if(depu < depv) swap(depu, depv), swap(u, v);//默认 u 的深度大 ll l = max(calc(1, depv - 1, depv - 1) + 1, u - calc(depv + 1, depu, depu - depv));ll r = min(calc(1, depv, depv), u - calc(depv, depu - 1, depu - depv));//求 u 到 depv 的能到的点的左右边界  cnt += calc(depv, depu - 1, depu - depv);//这是到 depv 所需的距离 if(l <= v && v <= r) {cout << cnt << '\n';continue;}// 若可以直接到达,就是这个距离 if(v > r) cnt += calc(max(depv - (v - r), 1ll), depv - 1, v - r) * 2; //否则就是两种情况,这里让 u=r else cnt += calc(max(depv - (l - v), 1ll), depv - 1, l - v) * 2;//这里让 u=l cout << cnt << '\n';}return 0;
}
http://www.jsqmd.com/news/925097/

相关文章:

  • 072、千万级图片去重怎样快?二阶段召回:感知哈希粗筛 + 局部特征精排方案
  • Kubernetes网络策略:实现Pod间的网络隔离
  • 稳定性保障实践:构建高可用系统的工程艺术
  • 3步掌握微信聊天记录永久保存:WeChatMsg免费工具终极实战
  • ESP32物联网开发终极方案:5大核心架构设计与实战指南
  • 麒麟V10系统盘告急?别慌!手把手教你挂载新硬盘并秒配可用Yum源(避坑local.repo)
  • CSDN平台的AI数字营销平台价格体系与性价比个人评价
  • 关于fluid打字机问题的解决记录
  • 【Gemini企业部署黄金 checklist】:97%团队忽略的5项合规性配置与安全审计红线
  • 基于Arduino Leonardo的DIY游戏控制器:为残障人士打造低成本辅助设备
  • 告别混乱日程:在统信UOS中用WeekToDo打造你的专属GTD工作流
  • UVa 346 Getting Chorded
  • 电路设计入门:从欧姆定律到PCB实战,点亮你的硬件创造之旅
  • 咸阳奥克斯空调维修加冷媒|人民中路老店 30 分钟上门 - GrowthUME
  • 如何永久保存微信聊天记录:5分钟掌握WeChatMsg完整数据备份方案
  • langchain如何调用模型?一文详解
  • 电路设计入门:从零开始制作光控夜灯与数字逻辑电路
  • 量化系统难题1_复权后的日k数据_已解决
  • Arduino与伺服马达制作简易互动宠物:从原理到实践
  • VMware macOS解锁神器:3步开启苹果系统虚拟化之旅
  • 抖音音乐下载终极指南:免费开源工具实现批量处理与高效管理
  • 告别Windows字体丑!3步获取苹果苹方字体提升文档颜值
  • 2026年4月PE钢带波纹管实力厂家推荐,PE穿线管/MPP电力管/PVC排水管,PE钢带波纹管源头厂家口碑推荐 - 品牌推荐师
  • 多模态基础、图文大模型原理
  • 电路设计入门:从原理图到PCB,手把手教你制作可调光LED灯
  • Xenia Canary高级配置指南:5个核心技巧深度优化Xbox 360游戏模拟体验
  • 人民中路万家乐维修老店 咸阳专业热水器售后服务中心 - GrowthUME
  • 论文通关利器!常用的AI写作辅助网站,成稿速度破纪录
  • 基于PIR与ISD1820的120dB可定制语音报警系统设计与实现
  • AI应用的质量保障:从测试到监控的完整流程