1. 程式人生 > >Loj 2047 偽光滑數

Loj 2047 偽光滑數

bit getch nod ref str queue inline space ble

Loj 2047 偽光滑數

  • 正解較復雜,但這道題其實可以通過暴力解決.
  • 預處理出 \(128\) 內的所有質數,把 \(n\) 內的 \(prime[i]^j\) 丟進堆中,再嘗試對每個數變形,除一個質因子,再乘一個.
  • 保證最大值因子的次數為正就可以了,取 \(k\) 次堆頂即得答案.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pii pair<int,int>
inline ll read()
{
    ll x=0;
    bool pos=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar())
        if(ch=='-')
            pos=0;
    for(;isdigit(ch);ch=getchar())
        x=x*10+ch-'0';
    return pos?x:-x;
}
ll n,k;
struct node{
    ll a,b,c,d;
    node(ll a,ll b,ll c,ll d):a(a),b(b),c(c),d(d) {}
    bool operator < (const node &rhs) const
        {
            return a<rhs.a;
        }
};
bool isp(ll x)
{
    for(ll i=2;i*i<=x;++i)
        if(x%i==0) 
            return false;
    return true;
}
priority_queue<node> hp;
ll pr[130],cnt=0;
int main()
{
    n=read(),k=read();
    for(ll i=2;i<=128;++i)
        {
            if(isp(i))
                {
                    pr[++cnt]=i;
                    ll a=1;
                    for(ll j=1;a<=n/i;++j)
                        {
                            a*=i;
                            hp.push(node(a,i,0,0));
                            if(cnt>1 && j>1)
                                hp.push(node(a/i*pr[cnt-1],i,j-1,cnt-1));
                        }
                }
        }
    while(--k)
        {
            node cur=hp.top();
            hp.pop();
            ll a=cur.a,b=cur.b,c=cur.c,d=cur.d;
            if(d>1)
                hp.push(node(a/pr[d]*pr[d-1],b,c,d-1));
            if(c>1)
                hp.push(node(a/b*pr[d],b,c-1,d));
        }
    cout<<hp.top().a<<endl;
    return 0;
}

Loj 2047 偽光滑數