[ Pollard_rho ] BZOJ4522

来源:互联网 发布:windows 程序设计 编辑:程序博客网 时间:2024/05/22 17:13

按题意模拟就好了。

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define ll long long#define M 1000000007ll N,e,c,d,n,r,a[80],m;ll rt=233333333;inline ll Mul(ll x,ll y,ll m){    ll Ans=0;    for(;y;y>>=1,x=(x<<1)%m)if(y&1)Ans=(Ans+x)%m;    return Ans;}inline ll Pow(ll x,ll y,ll m){    ll Ans=1;    for(;y;y>>=1,x=Mul(x,x,m))if(y&1)Ans=Mul(Ans,x,m);    return Ans;}inline ll Gcd(ll x,ll y){    return y?Gcd(y,x%y):x;}inline ll Rnd(ll n){    rt=(rt*rt+2333333)%M;    return (double)rt/M*n+0.5;}inline bool Witness(ll a,ll n){    ll s=0,t=n-1;    while(!(t&1))s++,t>>=1;    ll x=Pow(a,t,n),y=x;    for(int i=1;i<=s;i++){        x=Mul(x,x,n);        if(x==1&&y!=1&&y!=n-1)return 1;        y=x;    }    return (x!=1);}inline bool Check(ll n){    if(n==2)return 1;    if(n<2||!(n%2))return 0;    for(int i=1;i<=10;i++){        ll x=Rnd(n-2)+1;        if(Witness(x,n))return 0;    }    return 1;}inline ll Pollard_rho(ll n,ll c){    ll x=Rnd(n-2)+1,i=1,k=2;    ll y=x;    while(1){        x=(Mul(x,x,n)+c)%n;        if(x==y)return n;        ll t=Gcd((y-x+n)%n,n);        if(t>1&&t<n)return t;        if(++i==k)y=x,k<<=1;    }}inline void Find(ll n,ll c){    if(n==1)return;    if(Check(n)){        a[++m]=n;        return;    }    ll t=n,k=c;    while(t==n)t=Pollard_rho(t,c--);    Find(t,k);Find(n/t,k);}inline ll Get(ll n){    m=0;    Find(n,150);    ll Ans=n;    sort(a+1,a+m+1);m=unique(a+1,a+m+1)-a-1;    for(int i=1;i<=m;i++)Ans=Ans/a[i]*(a[i]-1);    return Ans;}int main(){    cin>>e>>N>>c;    Find(N,150);    r=(a[1]-1)*(a[2]-1);    d=Pow(e,Get(r)-1,r);    n=Pow(c,d,N);    cout<<d<<" "<<n<<endl;    return 0;}
原创粉丝点击