POJ 1845 Sumdiv

模意义下的运算

对于一个数 \(N\) 来说,可以分解成 $$N=p_1 ^ {c_1}p_2^{c_2}\cdots P_m ^ {c_m}$$

\(N\) 的所有正约数的和可表示为:

\[(1 + p_1 + p_1 ^2 + \cdots p_1 ^ {c_1})* \cdots *(1 + p_m + p_m ^2 + \cdots + p_m ^{c_m}) = \prod_{i =1}^1(\sum_{j = 1}^{c_1}(p_j)^i) \]

对于 \(N^B\) 来说,所有正约数的和可表示为:

\[$$(1 + p_1 + p_1 ^2 + \cdots p_1 ^ {c_1 * B})* \cdots *(1 + p_m + p_m ^2 + \cdots + p_m ^{c_m * B}) = \prod_{i =1}^1(\sum_{j = 1}^{c_j * B}(p_j)^i) \]

那么对于每个质因数来说都是一个等差数列求和,运用等差数列求和公式做即可,对于除法来说,转换为乘上他的逆元, 因为 9901 是一个质数,所以对于 \(P_i - 1\)这个数来说,如果他不是 9901 的倍数,那么他就有逆元, 如果他是倍数,等差数列的公比就变为了 1

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define ll long long
using namespace std;
const int MOD = 9901;
ll Qfactor[100][2], tot, A, B, ans = 1ll;
void divide(ll n) {
	for(ll i = 2; i * i <= n; i++) {
		if(!(n % i)) {
			Qfactor[++tot][0] = i;
			while(!(n % i)) {Qfactor[tot][1]++; n /= i;}
		}
	}
	if(n > 1) {Qfactor[++tot][0] = n; Qfactor[tot][1] = 1;}
}
ll quick_mod(ll n, ll k) {
	ll ans = 1;
	while(k) {
		if(k & 1ll) (ans *= n) %= MOD;
		(n *= n) %= MOD;
		k >>= 1;
	}
	return ans;
}
int main() {
	cin>>A>>B;
	divide(A);
	for(int i = 1; i <= tot; i++) {
		if(!((Qfactor[i][0] - 1) % MOD)) (ans *= Qfactor[i][1] * B + 1) %= MOD;
		else {
			(ans *= (quick_mod(Qfactor[i][0], Qfactor[i][1] * B + 1) - 1 + MOD) % MOD) %= MOD;
			(ans *= quick_mod(Qfactor[i][0] - 1, MOD - 2)) %= MOD;
		}
	}
	cout<<ans<<endl;
	return 0;
}
posted @ 2018-03-11 19:51  Mr_Wolfram  阅读(84)  评论(0编辑  收藏  举报