zoukankan      html  css  js  c++  java
  • bzoj3643 Phi的反函数 数学 搜索

    链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3643

    题意:已知$x$,求出$phi(n)==x$的最小$n$。

    不得不说今天刷了一堆(相对而言)思博大爆搜之后来这么一道相对有思考价值的数学题真是强啊……

    首先我们需要记住一个基本事实:在$int$范围内,每个数的同一个质因数不会成为这个数字的$31$次方,一个数存在的不同质因数不会超过$10$个。

    理由很简单:首先$int_max==2147483647$,一定没有任何一个质数$31$次方小于这个数;至于第二个嘛……

    这个东西说明了一切……

    了解到这个之后,我们再回顾一下欧拉函数的性质,最重要的一点就在于:它是一个积性函数。于是我们就可以对着一个合数进行三种分类讨论:

    1)他自己就是一个质数的欧拉函数,那这个质数一定是他再加$1$;

    2)他是几个质数乘积,就递归搞下去。

    那么我们就爆搜就可以了。预处理出$sqrt(2147483647)$范围内的质数,然后利用这些扫来扫去,最后特判剩下的是不是质数即可。还有一个优化点:可以证明选择的质数一定是递增的,因此直接递增计算即可。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 const int maxn=50000;
     8 int prime[maxn],tot,n;bool notprime[maxn]={1,1};
     9 void shaisushu()
    10 {
    11     for(int i=2;i<=50000;i++)
    12     {
    13         if(!notprime[i])prime[++tot]=i;
    14         for(int j=1;j<=tot&&i*prime[j]<=50000;j++)
    15         {
    16             notprime[i*prime[j]]=1;
    17             if(!(i%prime[j]))break;
    18         }
    19     }
    20 }
    21 long long pro=1;long long ans=2147483648ll;int mudi;
    22 bool isprime(int x)
    23 {
    24     int mubiao=(int)sqrt(x);
    25     for(int i=1;prime[i]<=mubiao;i++)
    26         if(!(x%prime[i]))return 0;
    27     return 1;
    28 }
    29 void dfs(int now,int num)
    30 {
    31     int tpro=pro,tt=now;
    32     if(pro>=ans)return;
    33     if(now==1){ans=min(ans,pro);return;}
    34     if(now>mudi&&isprime(now+1)==1)ans=min(ans,pro*1ll*(now+1));
    35     if(prime[num]-1>mudi||now<prime[num]-1)return;
    36     for(int i=num;prime[i]<=mudi+1;i++)
    37     {
    38         if(prime[i]-1>now)return;
    39         if(!(now%(prime[i]-1)))
    40         {
    41             now/=(prime[i]-1);pro*=1ll*prime[i];
    42             dfs(now,i+1);
    43             while(!(now%prime[i]))
    44             {
    45                 now/=prime[i],pro*=1ll*prime[i];
    46                 dfs(now,i+1);
    47             }
    48             pro=tpro,now=tt;
    49         }
    50     }
    51 }
    52 int haha()
    53 {
    54     scanf("%d",&n);mudi=(int)sqrt(n);shaisushu();
    55     dfs(n,1);
    56     if(ans<=0x7fffffff)printf("%lld
    ",ans);else puts("-1");
    57 }
    58 int sb=haha();
    59 int main(){;}
    bzoj3643
  • 相关阅读:
    Azure PowerShell (2) 修改Azure订阅名称
    Windows Azure Platform Introduction (11) 了解Org ID、Windows Azure订阅、账户
    Azure PowerShell (3) 上传证书
    Azure PowerShell (1) PowerShell入门
    Windows Azure Service Bus (2) 队列(Queue)入门
    Windows Azure Service Bus (1) 基础
    Windows Azure Cloud Service (10) Role的生命周期
    Windows Azure Cloud Service (36) 在Azure Cloud Service配置SSL证书
    Android studio 使用心得(一)—android studio快速掌握快捷键
    android 签名、混淆打包
  • 原文地址:https://www.cnblogs.com/Loser-of-Life/p/7537748.html
Copyright © 2011-2022 走看看