难啊!
传送门
这道题不知道大家有没有看出来,其实是一道数论板题,Pollard rho算法板题。
其实特别难看出来,但只要我们一分析就什么都水落石出了。
分析
N = p ∗ q ① N = p * q\quad① N=p∗q①
r = ( p − 1 ) ∗ ( q − 1 ) ② r = (p - 1) * (q - 1)\quad② r=(p−1)∗(q−1)②
g c d ( r , e ) = 1 ③ gcd(r,e) = 1\quad③ gcd(r,e)=1③
e ∗ d ≡ 1 ( m o d r ) ④ e * d \equiv 1(mod\quad r)\quad④ e∗d≡1(modr)④
n e ≡ 1 ( m o d N ) ⑤ n^{e}\equiv 1(mod\quad N)\quad⑤ ne≡1(modN)⑤
c d ≡ n ( m o d N ) ⑥ c^{d}\equiv n(mod\quad N)\quad⑥ cd≡n(modN)⑥
已知: N , e , c N,e,c N,e,c
最后上代码:
#pragma GCC optimize(2)
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
LL p, q, T, e, N, c, d, n, r;
inline LL qkcheng (LL x, LL y, LL mod){
LL sum = 0;
x %= mod;
while (y){
if (y & 1)
sum = (sum + x) % mod;
x = (x << 1) % mod;
y >>= 1;
}
return sum;
}
inline LL qkpow (LL x, LL y, LL mod){
x %= mod;
LL sum = 1;
while (y){
if (y & 1)
sum = qkcheng (sum, x, mod);
x = qkcheng (x, x, mod);
y >>= 1;
}
return sum;
}
inline bool miller_rabin (LL n){
if (n == 2 || n == 3 || n == 5 || n == 7)
return 1;
if (!(n % 2) || !(n % 3) || !(n % 5) || !(n % 7))
return 0;
LL m = n - 1, k = 0;
while (!(m & 1)){
k ++;
m >>= 1;
}
for (register LL i = 1; i <= 1; i ++){
LL a = rand () % (n - 1) + 1, x = qkpow (a, m, n), y;
for (register LL j = 1; j <= k; j ++){
y = qkcheng (x, x, n);
if (y == 1 && x != 1 && x != n - 1)
return 0;
x = y;
}
if (y != 1)
return 0;
}
return 1;
}
inline LL gcd (LL x, LL y){
if (! y)
return x;
return gcd (y, x % y);
}
inline LL pollard_rho (LL n, LL c){
LL x = rand () % n, y = x, k = 2, i = 1;//全军出鸡,针对rand,你们的含精量呀?
while (1){
i ++;
x = (qkcheng (x, x, n) + c) % n;
LL d = gcd (fabs (x - y), n);
if (d > 1 && d < n)
return d;
if (x == y)
return n;
if (i == k){
y = x;
k <<= 1;
}
}
}
inline void Find (LL n){
if (miller_rabin (n)){
p = n;
return ;
}
LL tmp = n;
while (tmp >= n)
tmp = pollard_rho (tmp, rand () % (n - 1) + 1);
Find (tmp);
if (p)
return ;
Find (n / tmp);
}
inline LL exgcd (LL a, LL b, LL &x, LL &y){
if (! b){
x = 1, y = 0;
return a;
}
LL tmp = exgcd (b, a % b, y, x);
y = ((y - qkcheng(x, a / b, r) % r) % r + r) % r;
return tmp;
}
int main (){
srand (20060123);//注意,一定要写!!!
scanf ("%lld %lld %lld", &e, &N, &c);
Find (N);
q = N / p;
r = qkcheng ((p - 1), (q - 1), N);
LL x;
exgcd (e, r, d, x);
n = qkpow (c, d, N);
printf ("%lld %lld\n", d, n);
return 0;
}