5th Nov. 2019
有 \( n \) 袋米編號依序為 \( 1 \) 到 \(n \) ,其中一袋裝著全部都是壞掉的米,另外 \( n - 1 \) 袋裝的都是正常的米。已知一粒正常的米重\( 1 \) 單位,而一粒爛掉的米重 \( 0.1 \) 單位。現在,你有一個電子秤(可以告訴你重量)但是只能秤一次,請問你要怎麼知道爛掉的米是哪一袋?假設一袋的米夠多可以一直拿而不會取盡。
Ex. \( 5 \equiv 7 \pmod 2\) 、\( 7122 \equiv 12 \pmod 9 \)
不是都能除!
反例: \( 6 \equiv 12 \pmod 3 \) 但是\( 1 \not \equiv 2 \pmod 3 \)
a % b
就醬
給定一個數字 \( N \),定義 \(f(N) \) 為 「將\(1, 2, \dots, N\)寫在一起所成的數字。例:
\( f(4) = 1234 \),\( f(6) = 123456 \) 。
請問 \( f(N) \) 是否為 \( \text{suum} \) (\(3\)) 的倍數?
( \( N \leq 10^8 \) )
定理:每一個大於\(1\)的正整數都有一個唯一的質因數分解
證明:略
超爛...
int gcd(int a, int b){
while(b > 0){
a %= b;
swap(a, b);
}
return a;
}
int gcd(int a, int b){
return (!b ? a : gcd(b, a % b));
}
計算 \( a^x \pmod m \)
inline int modexp(int a, int b, int m){
int ans = 1;
for(int i = 0; i < b; i++){
ans = ans * a % m;
}
return ans;
}
計算 \(a^b \pmod m \) 需要 \( O(b) \) !
超爛啊,可不可以壓啊?
想要計算 \( a^x \),若知道\( t= a^{ \lfloor \frac{x}{2} \rfloor } \),那:
只會計算 \(a, a^2, a^4, \dots, a^{2^{\log x}} \),故複雜度變成 \(O(\log n) \)!
int modexp(int b, int e, int m){
if(!b) return 0;
if(!e) return 1;
int res = modexp(b, e/2, m);
res = res * res % m;
if(e % 2) res = res * b % m;
return res;
}
int modexp(int b, int e, int m){
int res = 1, current = 1;
for(int i = 0; (1LL << i) <= e; i++){
if((1LL << i) & e){
res = res * current % m;
}
current = current * current % m;
}
}
我們想要解這個:
不能除怎麼辦?
對於一個數字 \( a \) 和一個模數 \( m \), \( a\) 的模逆元 \( a^{-1} \) 就是滿足
的數字
不一定存在!條件: \( \gcd (a, m) = 1 \)
給定一個質數 \( p \) 和一個小於 \(p\) 的數字 \(a \) ,恆有
$$a \cdot 2a \cdot 3a \dots \cdot (p - 1)a \equiv 1 \cdot 2 \cdot 3 \dots \cdot (p - 1) \pmod p$$
$$(p - 1)! \cdot a^{p - 1} \equiv (p - 1)! \pmod p$$
故計算 \( a^{p - 2} \) 就可以計算模逆元!
(變強版輾轉相除)
貝祖定理:對於兩個\(a, b\),一定存在無限多組\(x, y \in \mathbb{Z} \) s.t. \(ax + by = \gcd(a, b) \)
證明:略。爽。
(變強版輾轉相除)
假設 \( \gcd(a, m) = 1 \),我們想要找到一個 \(b\) s.t. \(ab \equiv 1 \pmod m\)
(變強版輾轉相除)
$$ab \equiv 1 \pmod m$$
代表存在一個 \(k\) s.t.
$$ab - 1 = mk \implies ab - mk = 1$$
輸入 \((a, m)\),得到\(b, k\)即可!
void extgcd(int a, int b, int &x, int &y, int &d){
if(!b){
d = a;
x = 1;
y = 0;
return;
} else {
extgcd(b, a % b, x, y, d);
int newX, newY;
newX = y;
newY = x - a/b * y;
x = newX;
y = newY;
return;
}
}
參數才會爽
埃拉托斯特尼篩法
埃拉托斯特尼篩法
簡單明瞭
const int maxN = 1e5;
bool isPrime[maxN];
inline void sieve(){
for(int i = 0; i < maxN; i++) isPrime[i] = true;
isPrime[0] = isPrime[1] = false;
for(int i = 2; i < maxN; i++){
for(int j = 2 * i; j < maxN; j += i)
isPrime[j] = false;
}
}
質數倒數和更小:
$$\sum_{p \leq n} \frac{1}{p} = O(\log\log n)$$
故演算法為 \(O(N \log \log N)\)!
by Euler
因為\(p\)就會是\(i\)的最小質因數了(依序枚舉質數呀,第一個遇到的就是最小),所以之後的數字都會被\(p\)篩掉,不用急!
const int maxN = 1e5;
bool isPrime[maxN];
vector<int> primes;
inline void getPrime(){
for(int i = 0; i < maxN; i++) isPrime[i] = true;
for(int i = 2; i < maxN; i++){
if(isPrime[i]) primes.push_back(i);
for(int p : primes){
if(i * p > maxN) break;
isPrime[i * p] = false;
if(!(i % p)) break;
}
}
}
有一個數字 \(x \)
除\(3\)餘\(2\)
除\(5\)餘\(3\)
求 \(x\)?
除\(7\)餘\(2\)
$$x = a_1 \cdot m_2 \cdot (m_2^{-1} \pmod{m_1}) + a_2 \cdot m_1 \cdot (m_1^{-1} \pmod{m_2})$$
構造解:
模\(m_1\)為\(1\)
模\(m_2\)為\(1\)
另外一邊會消掉!
最後再模\(m_1m_2\)就好
若\((a_2 - a_1) \not \vert \gcd(m_1, m_2)\)則無解
否則可以解得\(k_1\)的值,然後代回去,得到某種
$$x = A + K \times \text{lcm}(m_1, m_2)$$
變成一條式子:
$$x \equiv A \pmod{\text{lcm}(m_1, m_2)}$$
vector<pair<int, int> > factorize(int n){
vector<pair<int, int> > vec;
pii res;
for(int p : primes){
if(p * p > n) break;
if(!(n % p)){
res.F = p;
res.S = 0;
while(!(n % p)){
res.S++;
n /= p;
}
}
}
if(n > 1) res.push_back({n, 1});
}