Sumdiv[POJ1845]

欢迎大家访问我的老师的OJ———caioj.cn

题面描述

传送门

思路

一句话题意:求 A B A^B AB的所有约数之和 mod ⁡ 9901 ( 1 ≤ A , B ≤ 5 ∗ 1 0 7 ) \operatorname{mod}9901(1\le A,B\le 5*10^7) mod9901(1A,B5107)

提要:

等比数列求和公式: S n = a 1 ∗ 1 − q n 1 − q S_n=a_1*\frac{1-q^n}{1-q} Sn=a11q1qn,其中 q q q为公比(与公差类似)

乘法逆元:

若整数 b , m b,m b,m互质,且 b ∣ a b\mid a ba,则存在一个整数x,使得 a / b ≡ a ∗ x ( mod ⁡ m ) a/b \equiv a*x(\operatorname{mod} m) a/bax(modm)
则称 x x x b b b m m m乘法逆元,记为 b − 1 ( mod ⁡ m ) b^{-1}(\operatorname{mod} m) b1(modm)

因为 a / b ≡ a ∗ b − 1 ≡ a / b ∗ b ∗ b − 1 ( mod ⁡ m ) a/b\equiv a*b^{-1}\equiv a/b*b*b^{-1}(\operatorname{mod} m) a/bab1a/bbb1(modm),所以 b ∗ b − 1 ≡ 1 ( mod ⁡ m ) b*b^{-1}\equiv 1(\operatorname{mod} m) bb11(modm)

如果 m m m是质数的话,并且 b &lt; m b&lt;m b<m,根据费马小定理,可知, b m − 1 ≡ 1 ( mod ⁡ m ) , 即 b ∗ b m − 2 ≡ 1 ( mod ⁡ m ) b^{m-1}\equiv 1(\operatorname{mod} m),即b*b^{m-2}\equiv 1(\operatorname{mod} m) bm11(modm)bbm21(modm)

因此,当模数 m m m为质数时, b m − 2 b^{m-2} bm2即为 b b b的乘法逆元

由于我们这里仅涉及到 m m m 9901 9901 9901,即为质数的情况,所以不做拓展。

由于A分解质因数,可表示为: p 1 c 1 ∗ p 2 c 2 ∗ . . . . . . ∗ p m c m p_1^{c_1}*p_2^{c_2}*......*p_m^{c_m} p1c1p2c2......pmcm,根据算术基本定理的“约数和”推论,

A B A^B AB的所有约数之和为: ( 1 + p 1 + p 1 2 + . . . . . . p 1 B ∗ c 1 ) ∗ . . . . . . ∗ ( 1 + p m + p m 2 + . . . . . . + p m B ∗ c m ) = ∏ i = 1 m ( ∑ j = 0 B ∗ c i ( p i ) j ) (1+p_1+p_1^2+......p_1^{B*c_1})*......*(1+p_m+p_m^2+......+p_m^{B*c_m})=\large\prod\limits_{i=1}^m(\sum\limits_{j=0}^{B*c_i}(p_i)^j) (1+p1+p12+......p1Bc1)......(1+pm+pm2+......+pmBcm)=i=1m(j=0Bci(pi)j)

仔细观察可以发现, ∑ j = 0 B ∗ c i ( p i ) j \sum\limits_{j=0}^{B*c_i}(p_i)^j j=0Bci(pi)j其实就是一个等比数列求和,

( p i B ∗ c i + 1 − 1 ) / ( p i − 1 ) (p_i^{B*c_i+1}-1)/(p_i-1) (piBci+11)/(pi1),这是我们只要对分子 p i B ∗ c i + 1 − 1 p_i^{B*c_i+1}-1 piBci+11快速幂求出,
分母通过快速幂,求出乘法逆元得出即可。

特别地,对于 p i − 1 p_i-1 pi1 9901 9901 9901的倍数,此时乘法逆元并不存在,但是 p 1 mod ⁡ 9901 = 1 p_1 \operatorname{mod} 9901 =1 p1mod9901=1,所以 1 + p 1 + p 1 2 + . . . . . . + p 1 b ∗ c 1 ≡ 1 + 1 + 1 2 + . . . . . . + 1 B ∗ c 1 ≡ B ∗ c 1 + 1 ( mod ⁡ 9901 ) . 1+p_1+p_1^2+......+p_1^{b*c_1}\equiv 1+1+1^2+......+1^{B*c_1}\equiv B*c_1+1(\operatorname{mod} 9901). 1+p1+p12+......+p1bc11+1+12+......+1Bc1Bc1+1(mod9901).

AC code

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<cstdlib>
#define ll long long
#define gc getchar()
using namespace std;
const int N=15;
const int mod=9901;
ll p[N];int c[N];
inline void qr(ll &x)
{
	x=0;int f=1;char c=gc;
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc;}
	while(c>='0'&&c<='9'){x=x*10+(c^48);c=gc;}
	x*=f;
}
inline void mul(ll &a,ll b)
{
	ll c=a*b/mod;
	a=a*b-c*mod;
}
inline ll pow_mod(ll a,ll b)
{
	ll ans=1;a%=mod;
	while(b)
	{
		if(b&1)mul(ans,a);
		b>>=1;mul(a,a);
	}
	return ans;
}
inline void div(ll x)
{
	p[0]=0;
	for(int i=2;i*i<=x;i++)
	{
		if(x%i==0)
		{
			p[++p[0]]=i;
			c[p[0]]=0;
			while(x%i==0)x/=i,++c[p[0]];
		}
	}
	if(x>1)p[++p[0]]=x,c[p[0]]=1;
}
int main()
{
	ll a,b;qr(a),qr(b);
	div(a);ll ans=1;
	for(int i=1;i<=p[0];i++)
	{
		if((p[i]-1)%mod==0)
		{
			ans=(b*c[i]+1)*ans%mod;
			continue;
		}
		ll x=pow_mod(p[i],b*c[i]+1);
		x=(x-1+mod)%mod;
		ll y=p[i]-1;
		y=pow_mod(y,mod-2);
		ans=ans*x*y%mod; 
	}
	printf("%lld\n",ans);
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值