HDU 1452 要求計算 S(2004^n) mod 29,其中 S(k) 為 k 的所有正因子之和(除數函數 σ₁(k))。
對於 n = p₁^a₁ p₂^a₂ ... pₖ^aₖ,除數函數具有積性:
σ₁(n) = σ₁(p₁^a₁) × σ₁(p₂^a₂) × ... × σ₁(pₖ^aₖ) σ₁(p^a) = 1 + p + p² + ... + p^a = (p^(a+1) - 1) / (p - 1)
2004 = 2² × 3 × 167
2004^n = 2^(2n) × 3^n × 167^n
利用積性:
S(2004^n) = S(2^(2n)) × S(3^n) × S(167^n)
= [(2^(2n+1)-1)/(2-1)] × [(3^(n+1)-1)/(3-1)] × [(167^(n+1)-1)/(167-1)]
= (2^(2n+1)-1) × (3^(n+1)-1)/2 × (167^(n+1)-1)/166
模算術中除法轉換為乘以模逆元:
a / b ≡ a × b⁻¹ (mod m),其中 b⁻¹ 滿足 b × b⁻¹ ≡ 1 (mod m) 模 29 下: 2⁻¹ ≡ 15 (因 2×15=30≡1) 166⁻¹ ≡ 18 (因 166≡166-5×29=21, 21×18=378≡1 mod 29)
ans = (2^(2n+1)-1) × 1
× (3^(n+1)-1) × 15
× (167^(n+1)-1) × 18
(mod 29)
long long mod_pow(long long a, long long b, long long mod) {
long long res = 1;
a %= mod;
while (b) {
if (b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
#include <bits/stdc++.h>
using namespace std;
const int MOD = 29;
long long mod_pow(long long a, long long b) {
long long res = 1;
a %= MOD;
while (b) {
if (b & 1) res = res * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return res;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
long long n;
while (cin >> n && n) {
long long term1 = (mod_pow(2, 2*n + 1) - 1 + MOD) % MOD;
long long term2 = (mod_pow(3, n + 1) - 1 + MOD) % MOD * 15 % MOD;
long long term3 = (mod_pow(167, n + 1) - 1 + MOD) % MOD * 18 % MOD;
long long ans = term1 * term2 % MOD * term3 % MOD;
cout << ans << '\n';
}
return 0;
}
(p^(a+1)-1)/(p-1)(x - 1 + MOD) % MOD 避免負數const int INF = 0x3f3f3f3f; // 約 1e9 // 優點:memset 可直接初始化陣列(每字節 0x3f) // 原理:0x3f3f3f3f = 1061109567,足夠大且無符號安全
此題完美展示了數論結構與模運算技巧在競賽程式設計中的實戰應用。