Acwing 97

Acwing 97. 约数之和

题意

\(a^b\)的约数之和

思路

假设不考虑次方,只求a的约数之和,要怎么求呢?
当遇到一个数b能被a整除时,假设当前答案为\(ans\),则应再加上\(ans*b\)
a经过质数分解定理后为\(p_1^{k1}p_3^{k3}p_3^{k3}...\)
当增加一个质数约数\(c^x\)时,则答案应变为\(ans*\sum_0^{i=x}c^i\)
运用快速幂的思想 ,当x为奇数,则有偶数个项,\(\sum_0^{i=x}c^i =(\sum_0^{i=\frac{x}{2}}c^i)*(c^{\lceil \frac{x}{2} \rceil}+1)\)
当x为偶数,则将x-1代入上式,多出的那个直接加到答案中

代码


int q_pow(int a,int b)
{
	int res=1;
	while(b)
	{
		if(b&1) res=(res*a)%mod;
		a=a*a%mod;
		b/=2;
	}
	return res;
}

int cal(int a,int b) 
{
	if(b==0) return 1ll;
	int res=0;
	if(b&1) 
	{	
		int k1=cal(a,b/2)%mod;
		int k2=(q_pow(a,(b+1)/2)+1)%mod;
		res=(res+k1*k2%mod)%mod;
	}
	else 
	{
		res=(res+q_pow(a,b))%mod;//多出来的那个
		int k1=cal(a,(b-1)/2)%mod;
		int k2=(q_pow(a,b/2)+1)%mod;
		res=(res+k1*k2%mod)%mod;
	}
	return res;
}

void solve() 
{
	cin>>n>>m;
	ans=1;
	if(n==0) {cout<<0<<endl;return;}
	for(int i=2;i<=n;i++) 
	{	
		if(n%i==0) 
		{
			int cnt=0;
			while(n%i==0) cnt++,n/=i;
			// ans*(i)
			if(i*m>0) ans=(ans*cal(i,cnt*m))%mod;
		}
	}
	cout<<ans<<endl;
}
posted @ 2023-02-24 22:12  Liang2003  阅读(14)  评论(0编辑  收藏  举报