Hướng dẫn giải của Bedao Mini Contest 10 - HIDDEN


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Tác giả: bedao

Nhận xét:

  • Với ~LCM(LCM(x, y),a) = T~ thì ~x, y~ và ~a~ đều là ước của ~T~.
  • Với ~A~ là một ước của ~T~, ~LCM(T,A) = T~.

Nếu ~a~ thỏa mãn là ước của ~T~, ta quy về bài toán tìm ~x, y~ là ước của ~T~ sao cho ~LCM(x,y) = T~ và ~1 < x,y < T~.

Giả sử có cặp ~x, y~ thỏa mãn thì sau khi phân tích ~x, y~ và ~T~ ra các thừa số nguyên tố, sẽ có ít nhất một thừa số nguyên tố có bậc của ~x~ bằng bậc của ~T~, thừa số đó ở ~y~ sẽ có bậc bé hơn của ~T~ và cũng có ít nhất một thừa số nguyên tố có bậc ở ~y~ bằng ~T~, có bậc của ~x~ bé hơn.

Đơn giản hóa, ~T~ có dạng ~T = P^k \times T'~, với ~T'~ là 1 ước của ~T~, ~P~ là một số nguyên tố, ~k~ lớn nhất có thể và ~k > 0~.

Ta tìm và gán ~x = P^k~, ~y = T / x~. Nếu ~y = 1~ tức là ~T~ là lũy thừa của một số nguyên tố, khi đó không tồn tại thừa số nguyên tố thứ hai cấu tạo lên ~T~.

Trong trường hợp không tồn tại thừa số nguyên tố thứ hai cấu tạo lên ~T~ hoặc ~T~ không chia hết cho ~a~, ta chắc chắn không tìm được cặp ~x, y~ thỏa mãn và in ra ~-1~. Việc tìm ~P~ ở đây rất đơn giản vì ~P \le sqrt(T)~ hoặc ~P = T~ (nếu ~T~ là số nguyên tố).

Độ phức tạp: ~O(sqrt(T))~.

Code mẫu

#include <iostream>
#include <stdio.h>
#include <vector>
#include <cmath>
#include <math.h>
#include <map>
#include <algorithm>
#include <set>
#include <bitset>
#include <queue>
#include <cstring>
#include <stack>
#include <iomanip>
#include <assert.h>

#define BIT(x,pos) (((x)>>(pos)) & 1LL)
#define _(x) (1LL<<(x))
#define bitCnt(x) __builtin_popcountll(x)
#define turnOn(x,pos) ((x) = (_(pos)))
#define turnOff(x,pos) ((x) &= ~(_(pos)))
#define flipBit(x,pos) ((x) ^= (_(pos)))
#define lowBit(x) ((x) & (-x))
#define turnAll(x) (_(x)-1LL)

#define name "test"
#define nameTask ""
#define fastIO ios::sync_with_stdio(false); cin.tie(0);

using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<int,ll> pil;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;

const int N = 1E6;

bool f[N+9];
vector<int> prime;
int pwA[N+9], pwT[N+9];
vector<int> numT, numA;
int a, T;

void sieve()
{
    f[1] = f[0] = 1;
    for (int i = 2;i <= trunc(sqrt(N)); ++i)
        if (f[i] == 0)
            for (int j = i*i;j <= N; j += i)
                f[j] = 1;

    for (int i = 2;i <= N; ++i)
        if (f[i] == 0) prime.push_back(i);
}

void factorize(int targetNum, vector<int> &listFact, int pw[N])
{
    for (int i = 0;i < (int)prime.size(); ++i)
    {
        int fact = prime[i];
        while (targetNum % fact == 0)
        {
            targetNum /= fact;
            if ((int)listFact.size() == 0 || listFact.back() != fact) listFact.push_back(fact);
            ++pw[fact];
        }
    }

    if (targetNum > 1)
    {
        listFact.push_back(targetNum);
        ++pw[targetNum];
    }
}

ll myPow(ll x, ll y)
{
    ll res = 1;
    while (y > 0)
    {
        if (y & 1) res = res * x;
        y = y >> 1;
        x = x * x;
    }
return res;
}

int myLCM(int x, int y)
{
    return x / __gcd(x,y) * y;
}

int main()
{
    if (fopen(name".INP","r"))
        freopen(name".INP","r",stdin),
        freopen(name".OUT","w",stdout);

    fastIO

    cin>>a>>T;

    sieve();
    factorize(a, numA, pwA);
    factorize(T, numT, pwT);

    vector<int> newT;
    for (int i = 0;i < (int)numT.size(); ++i)
    {
        int fact = numT[i];
        if (pwT[fact] > 0) newT.push_back(fact);
    }

    if ((int)newT.size() <= 1) return cout<<-1, 0;

    int x = 0, y = 0;
    if ((int)newT.size() >= 2)
    {
        int fact = newT[0];
        int pw = pwT[fact];
        x = myPow(fact, pw);

        fact = 0;
        pw = 0;
        ll res = 1;
        for (int i = 1;i < (int)newT.size(); ++i)
        {
            fact = newT[i];
            pw = pwT[fact];
            res *= myPow(fact, pw);
        }

        y = res;
    }

    if (myLCM(a,myLCM(x,y)) == T) return cout<<x<<" "<<y, 0;

    return cout<<-1, 0;
}

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.