GCD & LCM Inverse POJ - 2429(Pollard rho整数分解+dfs)

本文介绍了一种算法,用于解决给定最小公倍数(lcm)和最大公约数(gcd)的情况下找到两个整数a和b的问题。通过分解lcm/gcd并采用深度优先搜索策略来寻找满足条件且a+b最小的一对整数。

题目描述:给出lcm(a,b)和gcd(a,b),求a,b.

输入:输入数据有多组,每组占一行,包含两个整数gcd,lcm,这两个整数都小于2^63。

输出:对于每组测试数据升序输出a,b的值,如果有多组满足条件的a,b,则输出a+b最小的一对。

Sample Input
3 60
Sample Output
12 15

题目分析:因为(a*b)/gcd=lcm,那么(a/gcd*b/gcd)*gcd=lcm,因此(a/gcd * b/gcd)=lcm/gcd.题目即可转化为把lcm/gcd分解成两个互质的数使这两个的数和最小。只需将key=lcm/gcd

整数分解,然后深搜一下即可得到结果。代码如下:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<algorithm>
#define inf ((long long)1<<61)///infinite的缩写,意为无穷大
#define Times 11
#define N 1000
#define C 201
using namespace std;
unsigned long long key,a,b,gd,lm,res_a,res_b,mini;///res为result的简写
int ct;
long long factor[N];///存储质因子(含相同的)
long long gcd(long long a,long long b)
{
    if(b==0)
        return a;
    return gcd(b,a%b);
}
long long random(long long n)
{
    return (long long)((double)rand()/RAND_MAX*n+0.5);
}
long long multi(long long a,long long b,long long m)
{
    long long ans=0;
    while(b)
    {
        if(b&1)
        {
            ans=(ans+a)%m;
            b--;
        }
        b>>=1;
        a=(a<<1)%m;
    }
    return ans;
}
long long quick_mod(long long a,long long b,long long m)
{
    long long ans=1;
    a%=m;
    while(b)
    {
        if(b&1)
        {
            ans=multi(ans,a,m);
            b--;
        }
        b>>=1;
        a=multi(a,a,m);
    }
    return ans;
}
bool witness(long long a,long long n)///二次探测定理
{
    long long m=n-1;
    int j=0;
    while(m&1==0)
    {
        m>>=1;
        j++;
    }
    long long x=quick_mod(a,m,n);
    if(x==1||x==n-1)
        return false;
    while(j--)
    {
        x=x*x%n;
        if(x==n-1)
            return false;
    }
    return true;
}
bool miller_rabin(long long n)
{
    if(n==1) return false;
    if(n==2) return true;
    if(n&1==0) return false;
    for(int i=1;i<=Times;i++)
    {
        long long a=random(n-2)+1;
        if(witness(a,n)) return false;
    }
    return true;
}
long long pollard_rho(long long n,int c)///大整数的分解
{
    long long x,y,g;
    long long i=1,k=2;
    x=random(n-1)+1;
    y=x;
    while(1)
    {
        i++;
        x=(multi(x,x,n)+c)%n;
        g=gcd(y-x,n);
        if(g>1&&g<n)
            return g;
        if(y==x)
            return n;
        if(i==k)
        {
            y=x;
            k<<=1;
        }
    }
}
void find(long long n,int k)
{
    if(n==1)
        return ;
    if(miller_rabin(n))
    {
        ct++;
        factor[ct]=n;
        return ;
    }
    long long p=n;
    while(p>=n)
        p=pollard_rho(p,k--);
    find(p,k);
    find(n/p,k);
}
unsigned long long NumFactor[650];///存储质因子(不包含相同的)
int Num[65];///存储每个质因子的个数
int len;
void dfs(int cur,long long value)///cur为cursor的缩写,意为光标
{
    long long s=1;
    if(cur==len+1)
    {
        a=value;
        b=key/value;
        if(gcd(a,b)==1)
        {
            a*=gd;
            b*=gd;
            if(a+b<mini)
            {
                mini=a+b;
                res_a=a<b?a:b;
                res_b=a>b?a:b;
            }
        }
        return ;
    }
    for(int i=0;i<=Num[cur];i++)
    {
        if(value*s>=mini)
            return ;
        dfs(cur+1,value*s);
        s*=NumFactor[cur];
    }
}
void solve(long long n)///将factor中的质因子不重复的按从小到大的顺序存储到Numfactor[],
{                      ///同时Num[]记录每种素因子的个数
    ct=0;
    find(n,C);
    sort(factor+1,factor+ct+1);
    len=0;
    memset(Num,0,sizeof(Num));
    Num[0]=1;
    NumFactor[0]=factor[1];
    for(int i=2;i<=ct;i++)
    {
        if(NumFactor[len]!=factor[i])
        {
            len++;
            NumFactor[len]=factor[i];
        }
        Num[len]++;
    }
    dfs(0,1);
}
int main()
{
    while(scanf("%lld%lld",&gd,&lm)!=EOF)
    {
        if(gd==lm)
        {
            cout<<gd<<" "<<lm<<endl;
            continue;
        }
        mini=inf;///mini等于inf或-1都可以
        key=lm/gd;
        solve(key);
        cout<<res_a<<" "<<res_b<<endl;
    }
    return 0;
}


/etc /etc/systemd /etc/systemd/system /etc/systemd/system/haply-inverse-service.service /usr /usr/bin /usr/bin/00-haply-inverse-device-list /usr/bin/01-haply-inverse-print-inverse3 /usr/bin/02-haply-inverse-print-verse-grip /usr/bin/03-haply-inverse-print-wireless-verse-grip /usr/bin/04-haply-inverse-hello-floor /usr/bin/haply-inverse-service /usr/share /usr/share/doc /usr/share/doc/haply-inverse-service /usr/share/doc/haply-inverse-service/README /usr/share/doc/haply-inverse-service/copyright /usr/share/doc/haply-inverse-service/examples /usr/share/doc/haply-inverse-service/examples/tutorials /usr/share/doc/haply-inverse-service/examples/tutorials/00-haply-inverse-device-list /usr/share/doc/haply-inverse-service/examples/tutorials/00-haply-inverse-device-list/00-haply-inverse-device-list.cpp /usr/share/doc/haply-inverse-service/examples/tutorials/00-haply-inverse-device-list/CMakeLists.txt /usr/share/doc/haply-inverse-service/examples/tutorials/00-haply-inverse-device-list/README.md /usr/share/doc/haply-inverse-service/examples/tutorials/01-haply-inverse-print-inverse3 /usr/share/doc/haply-inverse-service/examples/tutorials/01-haply-inverse-print-inverse3/01-haply-inverse-print-inverse3.cpp /usr/share/doc/haply-inverse-service/examples/tutorials/01-haply-inverse-print-inverse3/CMakeLists.txt /usr/share/doc/haply-inverse-service/examples/tutorials/01-haply-inverse-print-inverse3/README.md /usr/share/doc/haply-inverse-service/examples/tutorials/02-haply-inverse-print-verse-grip /usr/share/doc/haply-inverse-service/examples/tutorials/02-haply-inverse-print-verse-grip/02-haply-inverse-print-verse-grip.cpp /usr/share/doc/haply-inverse-service/examples/tutorials/02-haply-inverse-print-verse-grip/CMakeLists.txt /usr/share/doc/haply-inverse-service/examples/tutorials/02-haply-inverse-print-verse-grip/README.md /usr/share/doc/haply-inverse-service/examples/tutorials/03-haply-inverse-print-wireless-verse-grip /usr/share/doc/haply-inverse-service/examples/tutorials/03-haply-inverse-print-wireless-verse-grip/03-haply-inverse-print-wireless-verse-grip.cpp /usr/share/doc/haply-inverse-service/examples/tutorials/03-haply-inverse-print-wireless-verse-grip/CMakeLists.txt /usr/share/doc/haply-inverse-service/examples/tutorials/03-haply-inverse-print-wireless-verse-grip/README.md /usr/share/doc/haply-inverse-service/examples/tutorials/04-haply-inverse-hello-floor /usr/share/doc/haply-inverse-service/examples/tutorials/04-haply-inverse-hello-floor/04-haply-inverse-hello-floor.cpp /usr/share/doc/haply-inverse-service/examples/tutorials/04-haply-inverse-hello-floor/CMakeLists.txt /usr/share/doc/haply-inverse-service/examples/tutorials/04-haply-inverse-hello-floor/README.md /usr/share/doc/haply-inverse-service/examples/tutorials/CMakeLists.txt /usr/share/doc/haply-inverse-service/examples/tutorials/CMakeSettings.json /usr/share/doc/haply-inverse-service/examples/tutorials/README.md /usr/share/doc/haply-inverse-service/examples/tutorials/external /usr/share/doc/haply-inverse-service/examples/tutorials/external/CMakeLists.txt /usr/share/doc/haply-inverse-service/examples/tutorials/external/json /usr/share/doc/haply-inverse-service/examples/tutorials/external/json/CMakeLists.txt /usr/share/doc/haply-inverse-service/examples/tutorials/external/json/LICENSE /usr/share/doc/haply-inverse-service/examples/tutorials/external/json/README.md /usr/share/doc/haply-inverse-service/examples/tutorials/external/libhv /usr/share/doc/haply-inverse-service/examples/tutorials/external/libhv.h /usr/share/doc/haply-inverse-service/examples/tutorials/external/libhv/CMakeLists.txt /usr/share/doc/haply-inverse-service/examples/tutorials/external/libhv/LICENSE /usr/share/doc/haply-inverse-service/examples/tutorials/external/libhv/README.md /usr/share/haply-inverse-service /usr/share/haply-inverse-service/assets /usr/share/haply-inverse-service/assets/audio /usr/share/haply-inverse-service/assets/audio/notification_test.wav /usr/share/haply-inverse-service/assets/dashboard /usr/share/haply-inverse-service/assets/dashboard/haply.png /usr/share/haply-inverse-service/assets/dashboard/index.html /usr/share/haply-inverse-service/assets/dashboard/style.css /usr/share/haply-inverse-service/assets/icons /usr/share/haply-inverse-service/assets/icons/haply.ico /usr/share/haply-inverse-service/assets/icons/haply.png /usr/share/haply-inverse-service/assets/icons/haply_on.ico /usr/share/haply-inverse-service/assets/icons/haply_on.png /usr/share/haply-inverse-service/assets/icons/haply_on_.ico
最新发布
07-27
### Haply Inverse Service 文件目录结构说明与安装配置指南 Haply Inverse Service 是 Haply 逆向触觉控制器的核心服务组件,负责与硬件通信并提供触觉反馈控制接口。该服务通常适用于基于 Debian 的 Linux 系统(如 Ubuntu),其文件分布遵循标准的 Linux 文件系统结构。 #### 文件目录结构说明 在系统中,`haply-inverse-service` 软件包的文件路径通常包括以下几个关键目录和文件: - **可执行文件**:位于 `/usr/bin/haply-inverse-service` 或 `/usr/sbin/haply-inverse-service`,用于启动服务进程。 - **配置文件目录**:`/etc/haply-inverse-service/`,其中包含主配置文件 `haply-inverse-service.conf` 和可能的设备映射文件。 - **服务单元文件**:`/lib/systemd/system/haply-inverse-service.service`,定义了 systemd 服务的启动参数和依赖关系。 - **日志文件目录**:`/var/log/haply-inverse-service/`,存储服务运行时的日志输出,便于调试和监控。 - **共享库文件**:`/usr/lib/x86_64-linux-gnu/libhaplyinverse.so`(或类似架构路径),提供 API 接口供其他应用程序调用。 - **文档与示例**:`/usr/share/doc/haply-inverse-service/`,包含 README、CHANGELOG 和示例配置文件。 #### 安装配置指南 安装 `haply-inverse-service` 通常通过 APT 包管理器完成,确保系统已添加 Haply 的官方仓库源,然后执行以下命令: ```bash sudo apt update sudo apt install haply-inverse-service ``` 安装完成后,可以通过以下命令启用并启动服务: ```bash sudo systemctl enable haply-inverse-service sudo systemctl start haply-inverse-service ``` 配置文件 `haply-inverse-service.conf` 通常位于 `/etc/haply-inverse-service/` 目录中,支持自定义端口、日志级别、设备路径等参数。例如: ```ini [General] LogLevel = debug DevicePath = /dev/haply/inverse3 Port = 8080 ``` 修改配置后,需重启服务以使更改生效: ```bash sudo systemctl restart haply-inverse-service ``` 若需调试服务运行状态,可通过以下命令查看日志输出: ```bash journalctl -u haply-inverse-service ``` 此外,Haply 提供了全面的 API 支持,开发者可以使用 C++、C# 或 Python 等语言与服务进行交互,并集成到虚拟现实引擎如 Unity3D 或 Unreal Engine 中[^2]。 ####
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值