自然因子之和 数学

【题目描述】
两个自然数 A 和 B .求 A^B 自然因子的总和。结果对 9901 取模输出
【输入】
两个自然数 A 和 B,空格隔开。
【输出】
输出: 和对 9901 取模的值。
【输入样例】
2 3
【输出样例】
15
【样例解释】
2^3 = 8
自然因子 8 是:1、2、4、8。
他们的 sum 是 15。
15 mod 9901 是 15 (这应该输出)。
【数据范围】
对于 20%的数据,0 <= A <= 50,0 <= B <= 10;
对于 100%的数据,0 < = A、B < = 50000000。


这道题的题解一大堆,可以用费马小定理,也可以先质因数分解,然后二分等比数列。

我这里用的是第二种方法:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>

#define ll long long
#define il inline
#define db double

#define mod 9901

using namespace std;

ll n,m;

il ll pow(ll a,ll b)
{
	ll ans=1;
	while(b)
		{
			if(b&1)
				ans=(ans*a)%mod;
			a=(a*a)%mod;
			b>>=1;
		}
	return ans;
}

int num[1000045],cnt;

int a[1000045];

il ll sum(ll p,ll n)
{
	if(n==0)
		return 1;
	if(n%2)
		return (sum(p,n/2)*(1+pow(p,n/2+1)))%mod;
	else
		return (sum(p,n/2-1)*(1+pow(p,n/2+1))+pow(p,n/2))%mod;
}

int main()
{
	freopen("sumdiv.in","r",stdin);
	freopen("sumdiv.out","w",stdout);

	cin>>n>>m;

	int sq=sqrt(n);

	for(int i=2;i<=sq;i++)
		{
			if(n%i==0)
				num[++cnt]=i;//记录质因数
			while(n%i==0)
				{
					n/=i;
					a[cnt]++;//记录次方
				}
		}
	
	if(n>1)
		{
			num[++cnt]=n;
			a[cnt]=1;
		}

	ll ans=1;
	for(int i=1;i<=cnt;i++)
		{
			a[i]*=m;
			ans=ans*sum(num[i],a[i])%mod;
		}

	printf("%lld
",ans);

	return 0;
}
原文地址:https://www.cnblogs.com/gshdyjz/p/7700259.html