题解 P1593 【因子和】

· · 题解

博客传送门

题意简述:

a^b的所有因子和

解题思路:

既然要求因子和,那我们必然要先分解质因数

根据整数的唯一分解定理,整数a进行质因数分解对应的式子唯一,有:

a = p_1^{k_1} * p_2^{k_2} *p_3^{k_3}* … * p_n^{k_n}

又因为本题要分解的是a^b,所以上面的式子又可以写成这样:

a^b= p_1^{k_1*b} * p_2^{k_2*b} *p_3^{k_3*b}* … * p_n^{k_n*b}

证明很简单,就是把上面第一个式子乘上b次即可得第二个式子

接下来我们要求的是因子和,

所以就有:

ans= (1+p_1^1 + p_1^2 +p_1^3+ … + p_1^{k_1*b})*(1+p_2^1 + p_2^2 +p_2^3+ … + p_1^{k_2*b})*...*(1+p_n^1 + p_n^2 +p_n^3+ … + p_n^{k_n*b})

对于上面的式子是不是有点熟悉?

对,你没有看错,就是等比数列之间的乘积

根据等比数列求和公式:

sum=\frac{p^{n}-1}{p-1}

我们就能求出各数列的和,

对于p^{n+1},我们用快速幂求

又因为本题要求的答案要对9901取模

故我们又可以通过逆元将除p-1转化为乘p-1的逆元

接下来要求逆元,根据定义,在mod\ p的意义下,对于一个整数a,有:

a*x≡1(mod\ p) 注意此处的$a,p$均与上文的意义不同,仅作为公式中的未知数 当$a,p$不互质时,逆元不存在,即上面的式子要满足: $$gcd(a,p)=1$$ 那么这个$x$怎么求? 那我们再引入一个定理,费马小定理: 假如$a$是一个整数,$p$是一个质数,那么当$a$是$p$的倍数时,有: $$a^p≡a(mod\ p)$$ 当$a$不是$p$的倍数时,有: $$a^{p-1}≡1(mod\ p)$$ 对于本题,显然我们要用的是第二种情况,第二种情况又可以变形为: $$a*a^{p-2}≡1(mod\ p)$$ 上式恰好对应逆元的定义式,故$a$在$mod\ p$意义下的逆元为$a^{p-2} 那逆元不存在怎么办,不用担心,因为对应上面的式子$p-1$,有: $$(p-1) \ mod \ 9901=0$$ 即: $$p \ mod \ 9901=1$$ 所以该等比数列之和($mod\ p$意义下)为: $$sum= 1+({p\ mod\ 9901})^1 +({p\ mod\ 9901})^2 +({p\ mod\ 9901})^3+ … + ({p\ mod\ 9901})^{n}$$ 即: $$sum=1+n$$ 至此,本题就分析完了 #### 代码实现: ```cpp #include<iostream> #include<cstdio> #define mod 9901 using namespace std; int a,b,sa,n[10010][2],cot=0,ans=1; int quick_pow(int ml,int nl)//快速幂 { int s=1; while(nl>0) { if(nl%2==1) { s=(s%mod)*(ml%mod)%mod; } ml=ml*ml%mod; nl=nl>>1; } return s%mod; } int sum(int x,int y) { int k=0; y=y*b; if(x%mod==1) { k=(y+1)%mod;//当逆元不存在时 } else { k=(quick_pow(x%mod,y+1)-1)%mod*quick_pow((x-1)%mod,mod-2)%mod;//当逆元存在时 } return k%mod; } int main() { scanf("%d%d",&a,&b); if(a==0)//特判,0的因数和就是0 { printf("0\n"); return 0; } for(int i=2;i*i<=a;i++)//分解质因数 { if(a%i==0) { cot++; n[cot][0]=i;//记录质因数 n[cot][1]=1;//记录幂次 a=a/i; while(a%i==0) { n[cot][1]++;//记录幂次 a=a/i; } } } if(a!=1)//可能a仍为因子 { cot++; n[cot][0]=a; n[cot][1]=1; } for(int i=1;i<=cot;i++) { ans=ans*sum(n[i][0],n[i][1])%mod; } printf("%d\n",(ans%mod+mod)%mod); return 0; } ``` 有用的话点个赞顶上去才能让更多人看到哦QAQ