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);
    }
    
  • 相关阅读:
    tyvj 1031 热浪 最短路
    【bzoj2005】 [Noi2010]能量采集 数学结论(gcd)
    hdu 1394 Minimum Inversion Number 逆序数/树状数组
    HDU 1698 just a hook 线段树,区间定值,求和
    ZeptoLab Code Rush 2015 C. Om Nom and Candies 暴力
    ZeptoLab Code Rush 2015 B. Om Nom and Dark Park DFS
    ZeptoLab Code Rush 2015 A. King of Thieves 暴力
    hdoj 5199 Gunner map
    hdoj 5198 Strange Class 水题
    vijos 1659 河蟹王国 线段树区间加、区间查询最大值
  • 原文地址:https://www.cnblogs.com/suika/p/9127096.html
Copyright © 2011-2022 走看看