poj1845 Sumdiv

\(a\) 分解成 \(p_1^{a_1} \cdot p_2^{a_2} \cdots p_n^{a_n}\),则 \(a^b=p_1^{a_1b} \cdot p_2^{a_2b} \cdots p_n^{a_nb}\)。约数和即

\[(1+p_1+p_1^2+\cdots+p_1^{a_1b})\times \cdots \times (1+p_n+p_n^2+\cdots+p_n^{a_nb}) \]

发现每一个括号里头都是 \((p_i^{a_ib+1}-1)/(p_i-1)\),考虑乘法逆元,发现当 \(9901|(p_i-1)\) 时是不可以的。但此时 \(p_i \equiv 1 \pmod {9901}\),那一项就成了 \((1+1+1^2+\cdots+1^{a_ib})=a_ib+1\) 直接乘就好了。

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
int a, b, num[25], cnt[25], din, ans=1;
void getYue(int a){
	for(int i=2; i*i<=a; i++)
		if(a%i==0){
			num[++din] = i;
			while(a%i==0)	a /= i, cnt[din]++;
		}
	if(a>1)	num[++din] = a, cnt[din] = 1;
	for(int i=1; i<=din; i++)
		cnt[i] *= b;
}
int ksm(int a, int b, int p){
	int re=1;
	while(b){
		if(b&1)	re = (re * a) % p;
		a = (a * a) % p;
		b >>= 1;
	}
	return re;
}
int main(){
	cin>>a>>b;
	getYue(a);
	for(int i=1; i<=din; i++){
		if((num[i]-1)%9901==0)	ans = (ans * (cnt[i]+1)) % 9901;
		else	ans = (ans * (ksm(num[i]%9901,cnt[i]+1,9901)-1+9901)%9901 * ksm((num[i]-1)%9901,9901-2,9901)%9901)%9901;
	}
	cout<<ans<<endl;
	return 0;
}
posted @ 2018-03-05 10:51  poorpool  阅读(113)  评论(0)    收藏  举报