Phi的反函数

P4780 Phi 的反函数

update 2023/2/17 作者笔误

\(\varphi\) 定义

\(\varphi(n)\) 代表从 \(1-n\) 所有与 \(n\) 互质的数的个数。

\(~\varphi(n)~\)

普通求法:

首先将 \(n\) 唯一分解为:

$n=x_1^{p_1}\times x_2^{p_2}……{\times} x_n^{p_n} $

\(\varphi(n)=n{\times} (1-\frac1{x_1}){\times} (1-\frac1{x_2}){\times} ……{\times} (1-\frac1{x_n})\)

证明:

首先我们考虑在所有数中有 \(\frac{1}{x}\) 的概率会取到一个数是 \(x\) 的倍数,那么有 \((1-\frac{1}{x})\) 的概率会取到一个数不是 \(x\) 的倍数, \(1-n\)\(n\) 个数,我们要找到 \(1-n\) 所有与 \(n\) 互质的数,也就是去一个不是 \(n\) 的任意一个因数 \((x_1,x_2,x_3……x_n)\) 的倍数,就得到以上式子。

两个定理:

\[1.\begin{cases} \varphi(nm)=\varphi(n){\times} \varphi(m)~~~~~\gcd(n,m)=1\\ \varphi(nm)=\varphi(n){\times} m~~~~~~~~~~~\gcd(n,m)=m \end{cases} \]

定理 1 证明:

\(\gcd(n,m)=1\) 情况下可以推导:

$n=x_1^{p_1}{\times} x_2^{p_2}……{\times} x_n^{p_n} $

$m=y_1^{q_1}{\times} y_2^{q_2}……{\times} y_n^{q_n} $

$n{\times} m=x_1^{p_1}{\times} x_2^{p_2}……{\times} x_n^{p_n}{\times} y_1^{q_1}{\times} y_2^{q_2}……{\times} y_n^{q_n} $

\(\varphi(nm)=n{\times} m{\times} (1-\frac1{x_1})……{\times} (1-\frac1{x_n}){\times} (1-\frac1{y_1})……{\times} (1-\frac1{y_n})=\varphi(n){\times} \varphi(m)~~~~~~~~~~~~gcd(n,m)=1\)

  1. \(\gcd(n,m)=m\) 情况下

考虑感性理解, \(1-n\) 里面有 \(\varphi(n)\) 个与 \(n\) 互质,那么扩大 \(m\) 倍,相当于有 \(m\)\(1-n\) 就直接乘(因为我们保证了 \(\gcd(n,m)=m\) 也就是 \(n\)\(m\) 的倍数,所以不存在乘上 \(m\) 后多出了不属于 \(n\) 的因子)。

定理 2.\(\varphi(n)=n-1~~~~~~~~~~~~~n\in prim\)(这显而易见)

我们需要求 Phi 的反函数就要先深刻理解上述内容然后进行运用

可以根据上述定理 1 得到:

(在这里我们用到了定理一第一类和定理一第二类的一种特殊情况 \(~\varphi(n{\times} n)=\varphi(n){\times} n~\)

得出
\(~\varphi(x)=\varphi(a_1){\times} a_1^{p_1-1}{\times} \varphi(a_2){\times} a_2^{p_2-1}{\times} ......\varphi(a_n){\times} a_n^{p_n-1}~~~~~~~~~~~~~~~~~~a_i\in prime\)

由定理二得: \(a_i\) 都是质数,所以 \(\varphi(a_i)=a_i-1\)

所有质数分解出来不超过 \(10\) 个,因为\(2{\times} 3{\times} 5{\times} 7{\times} 11{\times} 13{\times} 17{\times} 19{\times} 23{\times} 29=6469693230\)

\(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~2^{31}=2147483648\)

所以可以直接暴力搜索。

(关于判断是否为质数的函数)

因为数据范围在 \(2^{31}\) ,如果我们求 \(2^{31}\) 范围内的质数,直接爆炸,

其实我们只需要找出 \(2^{16}\) 的质数,每次判断一下当前这个数 \(now+1\) (也就是 \(revphi(now)\) 是不是质数

例如 \(\varphi(x)=n=\varphi(3){\times} \varphi(10000000007)\)

第一次找到 \(\varphi(3)\) 处理以后,由于我们只找了 \(2^{16}\) 的质数,我们找不到 \(\varphi(1000000007)\) 在里面,我们需要每次判断当前这是数是不是质数。

具体的:

第一次判断 \(\varphi(3){\times} \varphi(1000000007)\) 显然不是质数。

除以 \(\varphi(3)\) 后变成了 \(\varphi(1000000007)\) 也就是 \(now=1e9+6\)

第二次判断 \((now+1)\in prime\) 那么直接把质数给除了,直接结束了。

那么怎么得出答案呢

\[1.\begin{cases} \varphi(nm)=\varphi(n){\times} \varphi(m)~~~~~\gcd(n,m)=1\\ \varphi(nm)=\varphi(n){\times} m~~~~~~~~~~~\gcd(n,m)=m \end{cases} \]

\(\varphi(x)=\varphi(a_1){\times} a_1^{p_1-1}{\times} \varphi(a_2){\times} a_2^{p_2-1}{\times} ......\varphi(a_n){\times} a_n^{p_n-1}~~~~~~~~~~~~~~~~~~a_i\in prime\)

我们再来重新看看这些式子:

可以看出最后的 \(ans=a_1{\times} a_1^{p_1-1}{\times} a_2{\times} a_2^{p_2-1}{\times} ......{\times} a_n{\times} a_n^{p_n-1}~\)

代码:

#include<bits/stdc++.h> 
#define ll long long 
using namespace std;
const int N=1e7+10;
int vis[N],s[30],tot=0,n,cnt=0;
ll ans=1e17+10,prim[N];
void shai(int x){
    for(int i=2;i<=x;i++){
        if(!vis[i]){
            prim[++tot]=i;
        }
        for(int j=1;j<=tot&&i*prim[j]<=x;j++){
            vis[prim[j]*i]=1;
            if(!i%prim[j]){
                break;
            }
        }
    }    
}//质数筛
bool is_p(ll x){
    for(int i=2;i* i<=x;i++){
        if(x%i==0){
            //cout<<x<<i<<endl;
            return 0;
        }
    }
    return 1;
}//判断是否为质数
void dfs(int now,int id,ll rev){//id代表当前干过的质数,是个优化
    if(now>=ans) return ;//简单优化
    if(now==1){
        ans=min(rev,ans);
        return ;
    }
    if(is_p(now+1)) dfs(1,id+1,rev*(now+1));
    for(int i=id;i<=tot;i++){
        if(now%(prim[i]-1)==0){
            int a=now;
            ll b=rev;
            a/=(prim[i]-1);b*=prim[i]; //定理1的情况1
            dfs(a,i+1,b);
            while(a%prim[i]==0){//定理1的情况2
                a/=prim[i];b*=prim[i]; 
                dfs(a,i,b);
            } 
        }
    }
}

int main(){
    scanf("%d",&n);
    shai(sqrt(n)+1);    
    dfs(n,1,1);
    if(ans==1e17+10){//无解或者太大了
        printf("-1");
    }else printf("%lld",ans);
    return 0;
}
//2147483647
posted @ 2023-01-15 19:05  He_Zi  阅读(133)  评论(0编辑  收藏  举报