bzoj4802: 欧拉函数

来源:互联网 发布:java编程实例300 编辑:程序博客网 时间:2024/06/06 01:07

链接

  http://www.lydsy.com/JudgeOnline/problem.php?id=4802

题解

  Pollard Rho裸题吧
  没啥好说的..

代码

//Pollard rho#include <cstdio>#include <algorithm>#include <map>#include <cstdlib>#define ll unsigned long longusing namespace std;map<ll,ll> ans;inline ll md(ll x, ll p){while(x>p)x-=p;return x;}inline ll mult(ll a, ll b, ll p){    ll t=a, ans=0;    for(;b;t=md(t+t,p),b>>=1)if(b&1)ans=md(ans+t,p);    return ans;}inline ll pow(ll a, ll b, ll p){    ll t=a, ans=1;    for(;b;t=mult(t,t,p),b>>=1)if(b&1)ans=mult(ans,t,p);    return ans;}inline bool MR(ll n){    ll t, u, i, x, y;    if(n==1)return 0;    if(n==2)return 1;    if(~n&1)return 0;    for(t=0,u=n-1;~u&1;u>>=1,t++);    for(int tim=20;tim;tim--)    {        y=x=pow(rand()%(n-1)+1,u,n);        for(i=1;i<=t;i++)        {            x=mult(x,x,n);            if(x==1 and y!=1 and y!=n-1)return 0;            y=x;        }        if(x!=1)return 0;    }    return 1;}ll gcd(ll a, ll b){return !b?a:gcd(b,a%b);}inline ll PR(ll n, ll c){    ll x, y, i, k, d;    x=rand(), y=x;    for(i=1,k=2;;i++)    {        x=(mult(x,x,n)+c)%n;        d=gcd(y>x?y-x:x-y,n);        if(1<d and d<n)return d;        if(x==y)return n;        if(i==k)k<<=1,y=x;    }}inline void find(ll n, ll c){    ll p;    if(n==1)return;    if(MR(n)){ans[n]++;return;}    for(p=PR(n,c);p==n;p=PR(n,++c));    find(p,c), find(n/p,c);}int main(){    ll n, phi; map<ll,ll>::iterator it;    srand(123);    scanf("%llu",&n);    find(n,1);    phi=n;    for(it=ans.begin();it!=ans.end();it++)        phi/=it->first, phi*=it->first-1;    printf("%llu",phi);    return 0;}
0 0
原创粉丝点击