• 求一个极大数的欧拉函数 phi(i)


    思路:

      因为当n>=1e10的时候,线性筛就不好使啦。所以要用一个公式

      φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn)

      证明详见:《公式证明:欧拉函数》

      Miller-Rabin算法:

        判断某个数是否是素数,不是素数则返回一个因子。

      Pollard-Rho算法:

        利用Miller-Rabin求出 质因数。

        具体的:

          如果当前的数不是质数,找质因数 再搜Rho(n/d)和Rho(d) 

          如果是质数(不一定准确),再去判断。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<set>
      5 #include<vector>
      6 #include<map>
      7 #include<string>
      8 #include<iomanip>
      9 #include<iostream>
     10 #include<cmath>
     11 #include<queue>
     12 using namespace std;
     13 #define ALL(x,S) for(x=S.begin();x!=S.end();x++)
     14 typedef long long LL;
     15 typedef long double real;
     16 bool pd_prime[10010];
     17 set<LL> S;
     18 set<LL>::iterator pos;
     19 LL n;
     20 void prepare()
     21 {
     22     int i,j;
     23     memset(pd_prime,1,sizeof pd_prime);
     24     pd_prime[1]=0;
     25     for(int i=2;i<=10000;i++)
     26     if(pd_prime[i])
     27     for(int j=2;j<=10000/i;j++)
     28     pd_prime[i*j]=0;
     29 }
     30 void addp(LL t)
     31 { S.insert(t);}
     32 LL gcd(LL a,LL b)
     33 {
     34     if(!b) return a;
     35     return gcd(b,a%b);
     36 }    
     37 LL mul(LL a,LL b,LL mod)
     38 {
     39     LL ans=0;
     40     while(b)
     41     {
     42         if(b&1)    ans=(ans+a)%mod;
     43         a=(a+a)%mod;
     44         b>>=1;
     45     }
     46     return ans;
     47 }
     48 LL pow(LL a,LL b,LL mod)
     49 {
     50     LL ans=1;
     51     while(b)
     52     {
     53         if(b&1)    ans=mul(ans,a,mod);
     54         b>>=1;
     55         a=mul(a,a,mod);
     56     }
     57     return ans;
     58 }
     59 bool MR(LL n,LL k)
     60 {
     61     LL s=n-1,w=0;
     62     while(!(s&1))
     63         w++,s>>=1;
     64     LL y=pow(k,s,n);
     65     if(y==1 || y==n-1)
     66         return 1;
     67     while(w--)
     68     {
     69         y=mul(y,y,n);
     70         if(y==n-1)
     71             return 1;
     72     }
     73     return 0;
     74 }
     75 bool prime(LL n)
     76 {
     77     if(n<=10000)
     78         return pd_prime[n];
     79     bool flag=1;
     80     for(int i=1;i<=50;i++)
     81     if(pd_prime[i])
     82     if(!MR(n,i))    flag=0;
     83     return flag;
     84 }
     85 void rho(LL n)
     86 {
     87     if(n==1)    return ;
     88     if(n==4)
     89     {
     90         addp(2);
     91         addp(2);
     92         return ;
     93     }
     94     if(prime(n))
     95     {
     96         addp(n);
     97         return ;
     98     }
     99     LL x,y,d,p;
    100     while(1)
    101     {
    102         x=2,y=2,d=1;
    103         p=mul(rand(),rand(),100000000);
    104         if(d==1)
    105         {
    106             x=(mul(x,x,n)+p)%n;
    107             y=(mul(y,y,n)+p)%n;
    108             y=(mul(y,y,n)+p)%n;
    109             d=gcd(abs(x-y),n);
    110         }
    111         if(d==n)    continue;
    112         rho(d);rho(n/d);
    113         return ;
    114     }
    115 }
    116 LL phi(LL x)
    117 {
    118     S.clear();
    119     rho(x);
    120     LL ans=x;
    121     ALL(pos,S)
    122             ans=ans/(*pos)*((*pos)-1);
    123     return ans;
    124 }
    125 int main()
    126 {
    127     freopen("phi.in","r",stdin);
    128     freopen("phi.out","w",stdout);
    129     prepare();
    130     scanf("%lld",&n);
    131     cout<<phi(n);
    132     return 0;
    133 } 
  • 相关阅读:
    小白的基金理财课
    Spring Security 入门原理及实战
    spring-data-rest的魔力 10分钟实现增删改查
    redis单点、redis主从、redis哨兵sentinel,redis集群cluster配置搭建与使用
    Netty开发redis客户端,Netty发送redis命令,netty解析redis消息
    使用Netty实现HTTP服务器
    Netty实现心跳机制
    SpringMVC是怎么工作的,SpringMVC的工作原理
    Netty 学习系列
    Mybatis 源码学习系列
  • 原文地址:https://www.cnblogs.com/CLGYPYJ/p/7635976.html
Copyright © 2020-2023  润新知