Processing math: 0%

Friday, November 15, 2013

Bài toán 1


Đề bài:
 Cho số tự nhiên a, tìm số tự nhiên n nhỏ nhất sao cho:     n^n  \vdots  a, 1 \leq a \leq 10^9  

Ý tưởng: 
Ta phân tích a thành các thừa số nguyên tố.    a = \prod_{i=1}^{k} p_{i}^{r_i} , với    p_i, i = \overline{1..n}  là các số nguyên tố.
Ta lại có:   n^n   \vdots  a \Rightarrow n  =  x\prod_{i=1}^{k} p_{i}
Vậy bây giờ ta chỉ cần tìm x nhỏ nhất sao cho   (xn)^{xn}    \vdots    a  
Thuật toán: 
Ta làm theo các bước ở ý tưởng
Ta cần giải quyết bài toán là tính a^n   mod  p  trong thời gian cho phép. 
Ta có:
(ab)^n  mod  p = (a^n   mod  p)(b^n  mod  p)   mod   p
Áp dụng đẳng thức trên và gọi f(n) = a^n  mod  p  
Ta được:
  f(n) = \left\{\begin{matrix}f([\frac{n}{2}])^2  mod  p,   n  \equiv 0  (mod   2) \\  af([\frac{n}{2}])^2  mod  p,  n  \equiv 1   (mod   2) \end{matrix}\right.  Vậy độ phức tạp của thuật toán chỉ là   O(log_{2}n)

Mã nguồn:

#include <iostream>

using namespace std;
typedef long long ll;

ll power(ll a, ll nint p) {
if (!n) return 1;
if (== 1) return a;
ll tmps = power(a>> 1, p) % p;
if  (& 1) return ((tmps*tmps) % p) * ap;
return tmps * tmps % p;
}

int main() {
int i = 2, A, p;
ll n = 1;
cin >> A; p = A;
while (i*i <= A) {
if (A % i == 0) n *= i;
while (A % i == 0) A /= i;
i++;
}
n = n*A;
i = 1;
while (power(i*n, i*n, p)) i++;
cout << i*n;
system("Pause");
return 0;
}


No comments:

Post a Comment