zoukankan      html  css  js  c++  java
  • BZOJ_4802_欧拉函数_MR+pollard rho+欧拉函数

    BZOJ_4802_欧拉函数_MR+pollard rho+欧拉函数

    Description

    已知N,求phi(N)

    Input

    正整数N。N<=10^18

    Output

    输出phi(N)

    Sample Input

    8

    Sample Output

    4

    直接MR+Pollard rho分解质因数即可。具体可见https://www.cnblogs.com/suika/p/9127065.html
    记得判重,我的map不知道为何T了。
     
    代码:
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    #include <cmath>
    #include <map>
    using namespace std;
    typedef long long ll;
    typedef double f2;
    map<ll,int>mp;
    ll ch(ll x,ll y,ll mod) {ll re=0;for(;y;y>>=1ll,x=(x+x)%mod) if(y&1ll) re=(re+x)%mod; return re;}
    ll random(ll x,ll y) {return ((rand()*(1ll<<45))+(rand()*(1ll<<30))+(rand()<<15)+(rand()))%(y-x+1)+x;}
    ll qp(ll x,ll y,ll mod) {ll re=1;for(;y;y>>=1ll,x=ch(x,x,mod)) if(y&1ll) re=ch(re,x,mod); return re;}
    ll a[]={2,3,5,7,11,13,17,19,23,29};
    ll ans;
    ll Abs(ll x) {return x>0?x:-x;}
    ll gcd(ll x,ll y) {return y?gcd(y,x%y):x;}
    ll b[250000];
    bool check(ll a,ll n,ll r,ll s) {
        ll x=qp(a,r,n),y=x,i;
        for(i=1;i<=s;i++,y=x) {x=ch(x,x,n); if(x==1&&y!=1&&y!=n-1) return 0;}
        return x==1;
    } 
    bool MR(ll n) {
        if(n<=1) return 0; ll r=n-1,s=0,i;
        for(;!(r&1);r>>=1ll,s++);
        for(i=0;i<=9;i++) {
            if(a[i]==n) return 1;
            if(!check(a[i],n,r,s)) return 0;
        }
        return 1;
    }
    ll f(ll x,ll c,ll mod) {return (ch(x,x,mod)+c)%mod;}
    ll PR(ll n,ll c) {
        ll x=random(0,n-1),y=f(x,c,n),p;
        for(p=1;p==1&&x!=y;) {
            x=f(x,c,n); y=f(f(y,c,n),c,n); p=gcd(Abs(x-y),n);
        }
        return p==1?n:p;
        /*ll k=2,x=rand()%n,y=x,p=1,i;
        for(i=1;p==1;i++) {
            printf("%lld %lld
    ",x,y);
            x=f(x,c,n); p=gcd(n,Abs(x-y)); if(i==k) y=x,k+=k;
        }
        return p;*/
    }
    void solve(ll n) {
        if(n==1) return ;
        if(MR(n)) {
            b[++b[0]]=n;
            return ; 
        }
        ll t=n;
        while(t==n) t=PR(n,rand()%n);
        solve(t); solve(n/t);
    }
    int main() {
        ll n;
        srand(19260817);
        scanf("%lld",&n); ans=n;
        int i;
        for(i=0;i<=9;i++) {
            if(n%a[i]==0) {
                ans=ans/a[i]*(a[i]-1); while(n%a[i]==0) n/=a[i];
            }
        }
        solve(n);
        int tot=unique(b+1,b+b[0]+1)-b-1;
        for(i=1;i<=tot;i++) ans=ans/b[i]*(b[i]-1); 
        printf("%lld
    ",ans);
    }
    
  • 相关阅读:
    《基于CMMI的软件工程及实训指导》第一章读书心得
    第一个微信小项目
    自己设计大学排名-数据库实践
    第一次爬虫和测试
    预测球队比赛成绩
    自己的第一个网页
    科学计算和可视化
    第一个微信小项目
    数据库实际
    第一个爬虫和测试
  • 原文地址:https://www.cnblogs.com/suika/p/9127096.html
Copyright © 2011-2022 走看看