Sumdiv
题意:给出两个数 n , m n,m n,m,求 n m n^m nm的全部因子的和 S S S对 9901 9901 9901取模的结果。
结论:
1. 唯 一 分 解 定 理 : 1.唯一分解定理: 1.唯一分解定理:
任 意 自 然 数 都 可 以 拆 成 质 因 子 乘 积 的 形 式 , n m = a 1 b 1 ∗ m ∗ a 2 b 2 ∗ m . . . ∗ a n b k ∗ m , 其 中 a 1 , a 2 . . . a k 都 是 n 的 质 因 子 , 例 如 396 = 2 2 ∗ 3 2 ∗ 1 1 1 任意自然数都可以拆成质因子乘积的形式,n^m = {a_1}^{b_1*m}*{a_2}^{b_2*m}...*{a_n}^{b_k*m},\quad其中a_1,a_2...a_k都是n的质因子,例如396 = 2^2*3^2*11^1 任意自然数都可以拆成质因子乘积的形式,nm=a1b1∗m∗a2b2∗m...∗anbk∗m,其中a1,a2...ak都是n的质因子,例如396=22∗32∗111
2. 利 用 结 论 1 和 排 列 组 合 知 识 ( 在 第 i 个 质 因 子 中 选 [ 0 , b i ] 个 ) : 2.利用结论1和排列组合知识(在第i个质因子中选[0,b_i]个): 2.利用结论1和排列组合知识(在第i个质因子中选[0,bi]个):
我 们 有 结 论 2 求 n m 的 全 部 因 子 的 和 S = ∏ i = 1 k ∑ j = 1 b i ∗ m a j , 将 S 拆 开 就 是 S = ( 1 + a 1 1 . . . + a 1 b 1 ∗ m ) ∗ ( 1 + a 2 1 . . . + a 2 b 2 ∗ m ) . . . ∗ ( 1 + a k 1 . . . + a k b k ∗ m ) 我们有结论2求n^m的全部因子的和S=\prod_{i=1}^k\sum_{j=1}^{b_i*m}{a^j} ,\quad将S拆开就是S=(1+{a_1}^1...+{a_1}^{b_1*m})*(1+{a_2}^1...+{a_2}^{b_2*m})...*(1+{a_k}^1...+{a_k}^{b_k*m}) 我们有结论2求nm的全部因子的和S=∏i=1k∑j=1bi∗maj,将S拆开就是S=(1+a11...+a1b1∗m)∗(1+a21...+a2b2∗m)...∗(1+ak1...+akbk∗m)
3. 等 比 数 列 的 求 法 : 分 治 3.等比数列的求法:分治 3.等比数列的求法:分治
T = 1 + a + a 2 . . . + a n T= 1+a+a^2...+a^n T=1+a+a2...+an
如 果 n 是 奇 数 的 话 T = ( 1 + a + a 2 . . . + a n / 2 ) ∗ ( 1 + a n / 2 + 1 ) 如果n是奇数的话T=(1+a+a^2...+a^{n/2})*(1+a^{n/2+1}) 如果n是奇数的话T=(1+a+a2...+an/2)∗(1+an/2+1)
如 果 n 是 偶 数 的 话 T = ( 1 + a + a 2 . . . + a n / 2 − 1 ) ∗ ( 1 + a n / 2 + 1 + a ) + a n / 2 如果n是偶数的话T=(1+a+a^2...+a^{n/2-1})*(1+a^{n/2+1}+a)+a^{n/2} 如果n是偶数的话T=(1+a+a2...+an/2−1)∗(1+an/2+1+a)+an/2
思路:利用结论 1 , 2 , 3 1,2,3 1,2,3求出结果,求 n m n^m nm的全部因子的和并在求的过程中不断取模。
C o d e Code Code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 9901;
map<ll, ll> M;//记录质因子的次数
//快速幂
ll qpow(ll a, ll b) {
ll ans = 1, res = a;
while(b) {
if(b & 1) ans = ans * res % mod;
res = res * res % mod;
b >>= 1;
}
return ans;
}
//等比数列求和
ll faction(ll a, ll b) {
if(b == 0) return 1;
if(b & 1) return faction(a, b/2)*(1+qpow(a, b/2+1)) % mod;
else return (faction(a, b/2-1)*(1+qpow(a, b/2+1)) + qpow(a, b/2))% mod;
}
int main() {
ll n, m, ans = 1;
cin >> n >> m;
//特判
if(n == 0) cout << 0;
else if(m == 0 || n == 1) cout << 1;
else {
//找到所有质因子。
for(int i=2; i*i<=n; ) {
while(!(n%i)) M[i]++, n/=i;
if(i == 2) i++;
else i += 2;
}
if(n != 1) M[n] = 1;//特判:n本来就是质数
for(map<ll, ll>::iterator it = M.begin(); it != M.end(); it++) {
ll a = it->first, b = it->second * m;
ans = ans * faction(a, b) % mod;//边乘边取模。
}
cout << ans % mod;
}
return 0;
}