Codeforces Round613 C 题——dfs+数论 | 暴力

题目链接:https://codeforces.com/contest/1285/problem/C

 题目描述:

给你一个数x(1<=x<=1e12),让你求出满足lcm(a,b)=x,且max(a,b)最小的a和b.

题解:很显然可以知道通过唯一分解定理,x可以分解为最多11个数,满足lcm(a,b)=x的条件是把x拆成两个数a,b。且a是一部分质因子的乘积(但是相同质因子的不能拆开,只能给一个数),b类似。举个例子,120=2*2*2*3*5,因此满足条件的是8*15,24*5,40*3,之后直接dfs就行了,时间复杂度2^11,比较简单.

更为直接的做法就是暴力枚举一下因子,维护符合条件的就行了。

代码实现:

#pragma GCC optimize(2)
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#define PI atan(1.0) * 4
#define E 2.718281828
#define rp(i, s, t) for (register int i = (s); i <= (t); i++)
#define RP(i, t, s) for (register int i = (t); i >= (s); i--)
#define ll long long
#define ull unsigned long long
#define mst(a, b) memset(a, b, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define pii pair<int, int>
#define mp make_pair
#define pb push_back
#define debug printf("ac\n");
using namespace std;
inline int read()
{
    int a = 0, b = 1;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-')
            b = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9')
    {
        a = (a << 3) + (a << 1) + c - '0';
        c = getchar();
    }
    return a * b;
}
const ll INF = 0x7ffffffff;
ll x;
bool Isprime(ll x)
{
    for (int i = 2; 1ll * i * i <= x; i++)
        if (x % i == 0)
            return false;
    return true;
}
const int N = 1e6;
ll prime[N + 7], isprime[N + 7];
int tot;
void init()
{
    tot = 0;
    mst(isprime, 1);
    // debug;
    for (ll i = 2; i <= N; i++)
    {
        if (isprime[i])
        {
            prime[tot++] = i;
            // debug;
            for (ll j = i * i; j <= N; j += i)
                isprime[j] = 0;
        }
    }
}
ll quick_pow(ll a, ll b)
{
    ll res = 1;
    while (b)
    {
        if (b & 1)
            res = (res * a);
        b >>= 1;
        a = (a * a);
    }
    return res;
}
ll res[N], ans;
ll Res;
void dfs(ll a, ll b, int x)
{
    if (x > ans - 1)
    {
        Res = min(Res, max(a, b));
        return;
    }
    dfs(a * res[x], b, x + 1);
    dfs(a, b * res[x], x + 1);
}
int main()
{
    scanf("%lld", &x);
    if (Isprime(x))
        printf("1 %lld\n", x);
    else
    {
        init();
        // printf("%lld\n",prime[tot-1]);
        ll temp = x;
        Res = x;
        ans = 0;
        for (int i = 0; i <= tot - 1; i++)
        {
            if (temp % prime[i] == 0)
            {
                int num = 0;
                while (temp % prime[i] == 0)
                    temp /= prime[i], num++;
                res[ans++] = quick_pow(prime[i], num);
            }
        }
        if (temp > 1)
            res[ans++] = temp;
        sort(res, res + ans);
        dfs(1, 1, 0);
        printf("%lld %lld\n", x / Res, Res);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值