[题解] abc465D-X to Y

文章内容

[AtCoder abc465_d] X to Y

涉及知识点:图论、树形结构、-叉树、最近公共祖先 (LCA)、双指针、数学(整除与取模)

问题描述

给你两个整数 ,还有一个不小于 的整数 。
有一个变量 ,初始值是 。你可以对 执行以下操作任意次(包括零次):

  • 选择一个整数 ,满足 或 ,然后把 的值替换成 。
    这里, 表示不大于实数 的最大整数。
    请你求出使得 的最少操作次数。题目保证在给定条件下,总能用有限步数让 。
    你需要处理 组测试数据,每组独立解答。

约束条件

  • 所有输入均为整数。

输入格式

输入从标准输入读取,格式如下:

plain text
T...

第 组测试数据 () 格式为:

plain text
X Y K

输出格式

请按顺序输出每组测试数据的答案,每个答案占一行。

样例 1

输入样例 1

plain text
411 9 30 0 2842 180 71948706013487601 48019760148910476 89014537

输出样例 1

plain text
2075

样例说明

看第一组测试数据。
通过下面的操作, 可以在两步内完成:

  • 选择 。因为 ,这个选择合法。然后把 的值改成 。
  • 选择 。因为 ,这个选择合法。然后把 的值改成 。
    不可能用少于两步完成,所以第一行输出 。

正解代码与思路讲解

算法核心思路

本题的本质是一个经典的**树上两点间最短路径(最近公共祖先 LCA)**问题。
如果我们把每个非负整数看作一个节点,由于任何数不断除以 最终都会变成 ,所有的数在“除以 ”的映射下其实构成了一棵以 为根节点的 -叉树。

  • 操作 1 ():代表在树上从当前节点向双亲节点移动一步。
  • 操作 2 ():代表在树上从当前节点向孩子节点移动一步。
    因此,从 变到 的最少操作次数,等价于求在这棵 -叉树中,节点 到节点 的最短路径长度。在树中,两点间的最短路径必然经过它们的最近公共祖先 (LCA)。我们只需分别找出 和 走到根节点 的所有祖先路径,再倒序比对找出它们分叉的位置即可。由于 且 ,树的最大深度不超过 层,所以暴力收集路径并查找 LCA 的单次时间复杂度为 ,效率极高。

正确 AC 代码

cpp
#include <bits/stdc++.h>using namespace std;#define int long long#define endl "\n" void solve() {    int x, y, k;    cin >> x >> y >> k;    vector<int> pathX, pathY;    // 1. 顺着树枝向上不断除以 k,收集 X 的所有祖先节点(直至根节点 0)    while (true) {        pathX.push_back(x);        x /= k;        if (pathX.back() == 0) break;    }    // 2. 同理,收集 Y 的所有祖先节点    while (true) {        pathY.push_back(y);        y /= k;        if (pathY.back() == 0) break;    }    // 3. 使用双指针从两端路径的末尾(即根节点 0)开始倒序向前比对    int i = pathX.size() - 1;    int j = pathY.size() - 1;    while (i >= 0 && j >= 0) {        // 只要发现两个祖先不相同,说明找到了分叉点,此时对应的上一个相同节点就是 LCA        if (pathX[i] != pathY[j]) break;        i--, j--;    }    // 4. 此时 pathX[0...i] 和 pathY[0...j] 是独立的分叉路径    // 它们各自到 LCA 的距离之和为 (i + 1) + (j + 1),精简后即为 i + j + 2    cout << i + j + 2 << endl;} signed main() {    ios::sync_with_stdio(false);    cin.tie(0);    int T = 1;    cin >> T;    while (T--) {        solve();    }    return 0;}

表示抽个倍数的方案数

表示抽k个数为的方案数

有

则

觉得不错?给作者点个赞吧

分类:题解

评论 (0)

无需注册,留言经站长审核后公开。

加载评论中…

[题解] abc465D-X to Y · Ensan 的博客