1. 程式人生 > >Math(數論-分解素因子)

Math(數論-分解素因子)

JATC's math teacher always gives the class some interesting math problems so that they don't get bored. Today the problem is as follows. Given an integer nn, you can perform the following operations zero or more times:

  • mul x: multiplies nn by x (where xx is an arbitrary positive integer).
  • sqrt: replaces n with n−−√n (to apply this operation, n−−√n must be an integer).

You can perform these operations as many times as you like. What is the minimum value of nn, that can be achieved and what is the minimum number of operations, to achieve that minimum value?

Apparently, no one in the class knows the answer to this problem, maybe you can help them?

Input

The only line of the input contains a single integer nn (1≤n≤1061≤n≤106) — the initial number.

Output

Print two integers: the minimum integer nn that can be achieved using the described operations and the minimum number of operations required.

Examples

Input

20

Output

10 2

Input

5184

Output

6 4

Note

In the first example, you can apply the operation mul 55 to get 100100and then sqrt to get 1010.

In the second example, you can first apply sqrt to get 7272, then mul 1818to get 12961296 and finally two more sqrt and you get 66.

Note, that even if the initial value of nn is less or equal 106106, it can still become greater than 106106 after applying one or more operations.

題意:輸入一個數,可以對這個數進行兩種操作:

           1.乘以任何一個數 x

           2.如果這個數為平方數(4,9,16,25…),可以對這個數開根號。

      求經過若干次操作後,這個數最小能變成哪個數?並輸出最少的變換次數。

思路:  首先我們知道對於任何一個數都可以轉換為:x=p1^a1 * p2 ^a2 * p3^a3 * ... * pn^an  (其中 pi 為素數)。

那麼我們來考慮平方數的特性 例如:4 = 2^2;   9 = 3^2 ;   16 = 2^4;  25 = 5^2;  36 = 2^2 * 3^2; 

由此我們可以知道只要將這個數 素因子分解,得到的素因子的指數都為偶數時,這個數為平方數那麼當所有的指數都為 1 時,此時這個數就是能夠變換到最小的那個數了。也就是說,我們現在要求的僅僅是將所有指數都變為1的操作步數,當然每次都開根號肯定是最快的了,也就是求最少步數的辦法那麼第一步我們就需要先將所有的指數統一轉換為 2^n ,這樣才能夠每次都是開根號,由於我們可以乘以任何一個數 x 。所以我們不需要管我們乘的是誰,只把指數轉變成滿足條件的最小的 2^n 即可,然後每次開根號,計算操作次數。

程式碼如下:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
#define LL long long
LL num[50010];
int book[1000010],p;
map<int,int>v;
void init() //打素數表
{
    p=0;
    for(int i=2; i<100010; i++)
    {
        if(!book[i])
        {
            num[p++]=(LL)i;
            for(int j=2*i; j<100010; j+=i)
                book[j]=1;
        }
    }
}
void work(LL &x,int &cnt)
{
    int maxx=1;
    LL z=1;//能夠轉換成的最小數
    for(int i=0; num[i]*num[i]<=x; i++) //分解素因數
    {
        if(x%num[i]==0)
        {
            int ans=0;
            while(x%num[i]==0)
            {
                x/=num[i];
                ans++;//指數的個數
            }
            z=z*num[i];//能夠轉換成的最小數
            maxx=max(maxx,ans);//最大指數
            v[ans]=1; //map去重,最後觀察右多少個不同的指數
        }
    }
    if(x!=1)//沒有除盡的話
    {
        z=z*x;
        v[1]=1;
    }
    x=z;
    cnt=0;
    if(maxx==1)return;//本身就是最小的

    LL s=1;//需要開多少次根號
    while(s<maxx)
    {
        cnt++;
        s<<=1;
    }
    if(s==maxx&&v.size()!=1)cnt++; //如果最大的指數就是2^n 但是其他指數不是2^n,因此第一步要乘以一個數
    else if(s!=maxx)cnt++;//如果最大的指數不是2^n, 因此第一步要乘以一個數

    return;
}
int main()
{
    LL n;
    init();
    scanf("%lld",&n);
    int ans;
    work(n,ans);
    printf("%lld %d\n",n,ans);
}