首页 > 基础资料 博客日记

洛谷P13016 [GESP202506 六级] 最大因数

2026-05-25 19:00:02基础资料围观12

这篇文章介绍了洛谷P13016 [GESP202506 六级] 最大因数,分享给大家做个参考,收藏极客资料网收获更多编程知识

当我看到数据范围的那一刻,\(10^9\)给我吓死了。

Solution

看到数据范围千万不要慌,先考虑直接建树,可是\(10^9\)不给你MLE就算好的了,于是考虑走一步看一步。
既然是两个节点的距离,那么就可以一直然当前大的节点先跳到父节点,同时让次数加一,直到节点相同再返回次数。
看到这儿你会发现,这题就是一个经典的LCA问题。怪不得我看标签有LCA
那么父节点怎么求呢???
实际聪明的你一定会发现,一个数的最大因数 = 这个数 / 这个数的最小因数,那么即可遍历 2 ~ n,一直找到这个数的最小因数,找到就返回 \(n / i\)

代码

#include<bits/stdc++.h>
using namespace std;
int f(int a){
    for(int i = 2; i <= a; i++)
        if(a % i == 0) return a / i;
}
int lca(int a, int b){
    int k = 0;
    while(a != b){
        if(a > b) a = f(a);
        else if(a < b) b = f(b);
        k++;
    }
    return k;
}
int main(){
    int q;
    cin >> q;
    while(q--){
        int x, y;
        cin >> x >> y;
        cout << lca(x, y) << endl;
    }
}

但是交上去你就会发现,只能喜提 \(60pts\) 的高分,那怎么优化呢?

优化

你会发现,过了 \(\sqrt{n}\) 的时候,就重复了,于是我们就只用遍历到 \(\sqrt{n}\) 就行了。
记得别忘了找不到就返回0!!!
根号就这样,凑合着看吧。

AC代码

#include<bits/stdc++.h>
using namespace std;
int f(int a){
    for(int i = 2; i <= sqrt(a); i++){
        if(a % i == 0) return a / i;
    }
    return 1;
}
int lca(int a, int b){
    int k = 0;
    while(a != b){
        if(a > b) a = f(a);
        else if(a < b) b = f(b);
        k++;
    }
    return k;
}
int main(){
    int q;
    cin >> q;
    while(q--){
        int x, y;
        cin >> x >> y;
        cout << lca(x, y) << endl;
    }
}

完结撒花 \ ^ _ ^ /


文章来源:https://www.cnblogs.com/AlgorithmInWang/p/20159563
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!

标签:

相关文章

本站推荐

标签云