• 济南学习 Day 5 T2 pm


    逆欧拉函数(arc)
    题目描述:
    已知phi(N),求N。
    输入说明:
    两个正整数,分别表示phi(N)和K。
    输出说明:
    按升序输出满足条件的最小的K个N。
    样例输入:
    8 4
    杨丽输出:
    15 16 20 24
    数据范围:
    对于20%的数据 phi(N)<=100
    对于40%的数据 phi(N)<=10^5
    对于80%的数据 phi(N)<=10^9
    对于100%的数据 phi(N)<=10^14,K<=1000
    其中有60%的数据满足K=1
    输入数据保证符合题意,且满足答案中最大的数不超过10^14。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<ctime>
     6 #define ll long long 
     7 using namespace std;
     8 const ll N=1e7;
     9 const ll M=1e5+10;
    10 ll n,k,tot,prime[N/10],ans[M];
    11 bool check[N+10];
    12 void prepare()
    13 {
    14     ll x=min(N,n*100);
    15     for(ll i=2,t;i<=x;i++)
    16     {
    17         if(!check[i]) prime[++tot]=i;
    18         for(ll j=1;j<=tot&&(t=prime[j]*i)<=x;j++)
    19         {
    20             check[t]=1;
    21             if(i%prime[j]==0) break;
    22         }
    23     }
    24 }
    25 ll mul(ll x,ll y,ll z)
    26 {
    27     ll r=0;
    28     for(;y;x<<=1,x%=z,y>>=1)
    29     {
    30         if(y&1)
    31           r+=x,r%=z,y--;
    32     }
    33 }
    34 ll Qc(ll x,ll y,ll z)
    35 {
    36     ll r=0;
    37     for(;y;x<<=1,x%=z,y>>=1)
    38       if(y&1)
    39         r=mul(r,x,z);
    40     return r;
    41 }
    42 bool is_prime(ll n)
    43 {
    44     if(n<2) return 0;
    45     if(n==2) return 1;
    46     if(!(n&1)) return 0;
    47     ll m=n-1,j=0;
    48     for(;!(m%1);j++,m>>=1);
    49     for(ll a,x,y,i=1;i<=5;i++)
    50     {
    51         a=rand()%(n-1)+1;
    52         x=Qc(a,m,n);
    53         for(ll k=1;k<=j;k++){
    54             y=mul(x,x,n);
    55             if(y==1&&x!=1&&x!=n-1) return 0;
    56             x=y;
    57         }
    58         if(x!=1) return 0;
    59     } 
    60     return 1;
    61 }
    62 void dfs(ll x,ll y,ll z)
    63 {
    64     if(x==1)
    65     {
    66         ans[++ans[0]]=y;return;
    67     }
    68     if(z<=0) return;
    69     if(x+1>prime[tot]&&is_prime(x+1)) ans[++ans[0]]=y*(x+1);
    70     for(ll a,b,c,i=z;i;i--)
    71     {
    72         if(x%(prime[i]-1)==0)
    73         {
    74             a=x/(prime[i]-1);b=y;c=1;
    75             while(a%c==0)
    76             {
    77                 b*=prime[i];
    78                 dfs(a/c,b,i-1);
    79                 c*=prime[i];
    80             }
    81         }
    82     } 
    83 }
    84 int main()
    85 {
    86     srand(time(0));
    87     scanf("%I64d%I64d",&n,&k);
    88     prepare();
    89     dfs(n,1,tot);
    90     sort(ans+1,ans+ans[0]+1);
    91     for(int i=1;i<=k;i++)
    92       printf("I64d ",ans[i]);
    93     return 0;
    94 }

    思路:

    算法一

    暴力枚举N,暴力求出phi(N)验证答案。

     

    时间复杂度:O(N^1.5)或O(N^2logN)或O(N^(5/4)logN)

    期望得分:20-50

    算法二

    在算法一的基础上,求phi用欧拉线性筛法。

     

    时间复杂度:O(N)

    期望得分:50

    算法三

    考虑到原数只可能有一个大于10^7的质因子。考虑将phi(N)分解,在10^7范围内从大到小暴力搜索质因子试除(从大到小搜索可使状态树上紧下宽),并记录对应的N。一个明显的优化就是如果当前数加一为大于10^7的一个质数(用Miller-Rabin素性测试判)就可以停止这一状态的继续搜索了。虽然看起来复杂度很吓人,不过由于满足条件的N较少等等种种原因,实测还是相当快的。

     

    时间复杂度:O(?)

    期望得分:100

  • 相关阅读:
    linux 下面 opcache 拓展
    php中函数前加&符号的作用分解
    apache 设置404页面
    nginx 环境搭建使用之入门
    curl获取http请求的状态码
    js打开新的窗体不被浏览器阻止
    YII 框架使用之——创建应用
    Yii 框架创建自己的 web 应用
    PHP中CURL方法curl_setopt()函数的一些参数
    Linux的学习--使用PuTTY
  • 原文地址:https://www.cnblogs.com/suishiguang/p/6041471.html
Copyright © 2020-2023  润新知