问题 G: 【数论】Sumdiv

求A^B次方的约数之和,
首先对A求约数之和就是
(1 + p1 + p1 ^ 2 + p1 ^ 3 + p1 ^ 4 + … p1 ^ a1) * (1 + p2 + p2 ^ 2 + p2 ^ 3 + p2 ^ 4 + … p2 ^ a2) *… (1 + pk + pk ^ 2 + pk ^ 3 + pk ^ 4 + … pk ^ ak) , 现在是A^B
那么就是求(1 + p1 + p1 ^ 2 + p1 ^ 3 + p1 ^ 4 + … p1 ^ (a1 * B)) * (1 + p2 + p2 ^ 2 + p2 ^ 3 + p2 ^ 4 + … p2 ^ (a2 * B)) *… (1 + pk + pk ^ 2 + pk ^ 3 + pk ^ 4 + … pk ^ (ak * B)) 在这里插入图片描述

#include <iostream>
using namespace std;
typedef long long ll ;
const int mod = 9901 ;
int p[11001] , n[11001] ;
ll qmi(ll a , ll b )
{
	ll res = 1 ;
	while(b)
	{
		if(b & 1) res = res * a % mod ;
		a = a * a % mod ;
		b >>= 1 ;
	}
	return res ;
}
ll sum(ll p , ll n)
{
	if(n == 0) return 1 ;
	if(n % 2 )
	 return sum(p , n / 2) * (1 + qmi(p , n / 2 + 1)) % mod ;
	else 
	 return (sum(p , n / 2 - 1) * (1 + qmi(p , n / 2 + 1)) + qmi(p , n / 2)) % mod ;
}
int main()
{
	int a , b ;
	while(cin >> a >> b)
	{
		int k = 0 ;
		for(int i = 2 ;i * i <= a ; i ++)
		 {
		 	if(a % i == 0)
		 	 {
		 	 	p[++ k] = i , n[k] = 0 ;
		 	 	while(a % i == 0)
		 	 	 n[k] ++ , a /= i ;	
			  }
			
		 }
		 if(a > 1) 
		  p[++ k] = a , n[k] = 1 ;
		 ll ans = 1 ;
		 for(int i = 1 ;i <= k ;i ++)
		  ans = (ans * sum(p[i] , n[i] * b) % mod) % mod ;
		 cout << ans << endl ;
	}
	return 0 ;
}
posted @ 2019-10-08 20:25  spnooyseed  阅读(87)  评论(0编辑  收藏  举报