ย - Last update: 2023-10-25
์ ์๋ก ๊ธฐ๋ณธ ์ ๋ฆฌ
Basic Functions
GCD (์ ํด๋ฆฌ๋ ํธ์ ๋ฒ)
- GCD(a,b)=GCD(b,r) (๋จ, r์ a๋ฅผ b๋ก ๋๋์์ ๋์ ๋๋จธ์ง)์ ๊ตฌํ์ด๋ค.
int gcd(int a, int b) {
return (b == 0) ? a : gcd(b, a % b);
}
int gcd(int a, int b) {
while (b != 0) {
int r = a % b;
a = b;
b = r;
}
return a;
}
LCM
int lcm(int a, int b) {
return a * b / gcd(a, b);
}
Simple isPrime
- ๋ฃจํธ ์๊ฐ๋ณต์ก๋์ด๊ธฐ ๋๋ฌธ์ N<1,000,000 ์ ๋์ผ ๋, ์๋นํ ์ ํจํ๋ค.
bool isPrime(int num) {
for(int i = 2; i * i <= num; ++i) {
if (num % i == 0) return false;
}
return true;
}
๋ฐ๋ฌ๋ผ๋น isPrime
- ํ๋ฅ ์ ์์ ํ์ ์ด์ง๋ง, ํน์ ์๋ค์ ๋ํด์ ๋ชจ๋ ์ฒดํฌํจ์ผ๋ก์จ ํ์ ์ ์ผ๋ก ์์ ์ฒดํฌ ๊ฐ๋ฅ
- casterian๋ ์ฝ๋ ์ฐธ๊ณ : https://casterian.net/archives/396
๐ ํผ์น๊ธฐ
typedef unsigned long long ull;
ull checker[] = {2ULL, 325ULL, 9375ULL, 28178ULL, 450775ULL, 9780504ULL, 1795265022ULL};
ull addmod(ull x, ull y, ull m) {
if (x >= m - y) {
return x - (m - y);
} else {
return x + y;
}
}
ull mulmod(ull x, ull y, ull m) {
ull r = 0ULL;
while (y > 0) {
if (y % 2 == 1)
r = addmod(r, x, m);
x = addmod(x, x, m);
y /= 2;
}
return r;
}
ull powmod(ull x, ull y, ull m) {
ull r = 1ULL;
while (y > 0) {
if (y % 2 == 1) {
r = mulmod(r, x, m);
}
x = mulmod(x, x, m);
y /= 2;
}
return r;
}
bool MR(ull N, ull A) {
ull d = N - 1;
while (d % 2 == 0) {
if (powmod(A, d, N) == N - 1) {
return true;
}
d /= 2;
}
ull tmp = powmod(A, d, N);
if (tmp == N - 1 || tmp == 1) {
return true;
} else {
return false;
}
}
bool isPrime(ull N) {
if (N <= 1) {
return false;
} else if (N == 2) {
return true;
} else if (N <= 10'000'000'000ULL) {
for (ull i = 3ULL; i * i <= N; i += 2) {
if (N % i == 0ULL) return false;
}
return true;
} else {
for (int i = 0; i < 7; i++) {
ull A = checker[i];
if (MR(N, A) == false) {
return false;
}
}
return true;
}
}
์๋ผ์คํ ํ
๋ค์ค์ ์ฑ(Sieve)
Slow version
vector<int> getPrimes int MAX) {
vector<int> memo(MAX + 1, 0);
vector<int> res;
for(int i = 2; i <= MAX; ++i) {
if (memo[i] != 0) continue;
res.push_back(i);
for(int j = i; j <= MAX; j += i) {
memo[j] = 1;
}
}
return res;
}
Fast version
vector<int> getPrimes(int MAX) {
vector<int> memo(MAX + 1, 0);
vector<int> res;
int i;
for(i = 2; i * i <= MAX; ++i) {
if (memo[i] != 0) continue;
res.push_back(i);
for(int j = i * i; j <= MAX; j += i) {
memo[j] = 1;
}
}
for(; i <= MAX; ++i)
if (memo[i] == 0)
res.push_back(i);
return res;
}
Linear Sieve
sp
์ ๋ค์ด์๋ ํด๋น ์ซ์์ ์ ์ผ ์์ ์์ธ์๋ ๋ค์ด๋ค.
vector<int> getPrimes(int MAX) {
vector<int> sp(MAX + 1, 0);
vector<int> res;
for(int i = 2; i <= MAX; ++i) {
if (sp[i] == 0) res.push_back(i);
for(auto& j: res) {
if (i * j > MAX) break;
sp[i * j] = j;
if (i % j == 0) break;
}
}
return res;
}
Time Complexity
- GCD: O(logA+logB)
- ํ๋ฒ ์ฌ๊ท๋ฅผ ๋ ๋๋ง๋ค ์ ์ด๋ ์๊ฐ 21โ์ด ๋๋ฏ๋ก, ๋ก๊ทธ ์๊ฐ๋ณต์ก๋๊ฐ ๋๋ค.
- LCM: O(logA+logB)
- Simple isPrime: O(Nโ)
- ๋ฐ๋ฌ๋ผ๋น isPrime: O(klog3N)
- k๋ ํ
์คํธํด์ผํ๋ ์ซ์์ ์
- ์๋ผ์คํ ํ
๋ค์ค์ ์ฑ ๊ตฌ์ฑ: O(NloglogN)
- Linear Sieve ๊ตฌ์ฑ: O(N)