bzoj 4522

断了好久的博客了…….似乎我太懒了。qwq。还是要开始写自己的了。

bzoj的题面好迷,但是我最终是在别人的博客那里看到了清晰的题面。

第一次写rho,抄了acdreamer的板子。qwq。

#include<cstdio>
#include<iostream>
#include<cstdlib>
#define rep(i,j,k) for(register int i = j; i <= k; i++)
#define dow(i,j,k) for(register int i = j; i >= k; i--)
#define ll long long
using namespace std;
 
inline ll read() {
    ll s = 0, t = 1; char c = getchar();
    while( !isdigit(c) ) { if( c == '-' ) t = -1; c = getchar(); }
    while( isdigit(c) ) s = s * 10 + c - 48, c = getchar();
    return s * t;
}
 
const int Times = 10;
inline void M(ll &x,ll p) { if( x >= p ) x -= p; }
 
inline ll mul(ll a,ll b,ll p) {
    ll ret = 0;
    while( b ) {
        if( b & 1 ) M(ret += a,p);
        M(a += a,p), b >>= 1;
    } return ret;
}
 
inline ll pow(ll x,ll t,ll p) {
    ll ret = 1;
    while( t ) {
        if( t & 1 ) ret = mul(ret,x,p);
        x = mul(x,x,p), t >>= 1;
    } return ret;
} 
 
int t = 0; ll fac[5];
inline ll gcd(ll x,ll y) { return !y ? x : gcd(y,x%y); }
inline ll pollard_rho(ll n,int c) {
    ll i = 1, k = 2, x = rand() % (n-1) + 1, y = x;
    while( 1 ) {
        i++;
        x = (mul(x,x,n) + c) % n;
        ll d = gcd((y - x + n) % n,n);
        if( 1 < d && d < n ) return d;
        if( x == y ) return n;
        if( i == k ) y = x, k <<= 1;
    }
}
 
inline bool miller_rabin(ll n) {
    if( n == 2 ) return 1;
    if( n < 2 || !(n & 1) ) return 0;
    ll m = n - 1; int k = 0;
    while( !(m & 1) ) m >>= 1, k++;
    rep(i,1,Times) {
        ll a = rand() % (n-1) + 1;
        ll x = pow(a,m,n), y;
        rep(j,1,k) {
            y = mul(x,x,n);
            if( y == 1 && x != 1 && x != n-1 ) return 0;
            x = y; 
        }
        if( y != 1 ) return 0;
    }
    return 1;
}
 
inline void find(ll n,int c) {
    if( n == 1 ) return;
    if( miller_rabin(n) ) {
        fac[t++] = n;
        return;
    }
    ll p = n; int k = c;
    while( p >= n ) p = pollard_rho(n,c--);
    find(p,k), find(n/p,k);
}
 
inline void exgcd(ll x,ll y,ll &a,ll &b) {
    if( !y ) a = 1, b = 0; 
    else exgcd(y,x%y,b,a), b -= a * (x / y);
}
 
inline ll niyuan(ll x,ll y) {
    ll a, b; exgcd(x,y,a,b);
    return (a % y + y) % y;
}
 
int main() {
    ll e = read(), N = read(), c = read();
    find(N,120);
    ll r = ((fac[0] - 1) * (fac[1] - 1)), d = niyuan(e,r), n = pow(c,d,N);
    cout<<d<<" "<<n<<endl;
    return 0;
}

  

 

posted on 2016-12-15 12:58  83131  阅读(144)  评论(0编辑  收藏  举报

导航