因子和
题目描述
输入两个整数 a和 b,求 a b a^b ab的因子和。
由于结果太大,只要输出它对 9901 取模的结果。
输入格式
仅一行,为两个整数 a 和 b。
输出格式
输出一行一个整数表示答案对 9901 取模的结果。
输入
2 3
输出
15
数据规模与约定
对于全部的测试点,保证保证 0≤b≤5×10^7 。
首先我们了解一下因子和咋求:
百度百科:算术基本定理,又称为正整数的唯一分解定理,即:每个大于1的自然数均可写为质数的积,而且这些素因子按大小排列之后,写法仅有一种方式。
即任何大于1的整数n可以唯一的表示成
n= p 1 a 1 {p_1}^{a_1} p1a1 p 2 a 2 {p_2}^{a_2} p2a2 p 3 a 3 {p_3}^{a_3} p3a3 p 4 a 4 {p_4}^{a_4} p4a4… p n a n {p_n}^{a_n} pnan
其因子和为: ( p 1 0 + p 1 1 + p 1 2 . . . . . (p_1^0+p_1^1+p_1^2..... (p10+p11+p12..... p 1 a 1 ) {p_1}^{a_1}) p1a1) ( p 2 0 + P 2 1 + p 2 2 . . . . . (p_2^0+P_2^1+p_2^2..... (p20+P21+p22..... p 2 a 2 ) {p_2}^{a_2}) p2a2)… ( p n 0 + p n 1 + p n 2 . . . . . (p_n^0+p_n^1+p_n^2..... (pn0+pn1+pn2..... p n a n ) {p_n}^{a_n}) pnan)
= ∏ i = 0 n \prod \limits_{i=0}^n i=0∏n P i a i + 1 − 1 p i − 1 \frac{{P_i}^{a_i+1}-1}{{p_i}-1} pi−1Piai+1−1怎么来的我不知道哈,请移步度娘。
然后怎么做嘞:(本题参考了洛谷题解,所以思路可以有点相似哦)
1:先把质因子,和他的幂次分解出来,用两个数组保存
举一个桃子吧,假如给定一个数字100;首先我们从第一个质数2开始
100%2==0 ,100/2=50,现在我们记录了2这个数字,幂次为1.
50%2==0,50/2=25 质因子2的幂次加一为2;
25%2!=0; i++;一直到下一个能被整除的,
25%5==0 25/5=5;现在记录5这个数字,幂次为1
5%5==0 5/5=1质因子2的幂次加一为2,最终我们得到100分解为因子是 2 2 5 5 。
2:利用保存的质因子及其幂次,连乘(哦对,中间求逆元的时候还有一个坑,当 p i p_i pi是质数但是 ( p i − 1 ) (p_i - 1) (pi−1)的值是取模值的倍数的时候,就不能直接用逆元了,但是 p i % m o d p_i \% mod pi%mod目前是等于1啊,也不复杂,即 ( 1 + p i 1 + p i 2 + ⋯ + p i a i ) % P (1+ p_i ^1+p_i^{2}+\cdots+p_i^{a_i})\%P (1+pi1+pi2+⋯+piai)%P= ( 1 + 1 + 1 + ⋯ + 1 ) (1+1+1+\cdots+1) (1+1+1+⋯+1)= a i + 1 a_i+1 ai+1
还有就是。。。取模。。记得取模。。必须取模。。永远取模。。好了,散了,自己动动手吧~
完整代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mod 9901
int a,b,zyz[10000],mc[10000],num=0;//zyz是质因子,mc对应着幂次,num记录有多少个不同的质因子相乘
ll ans=1;//最后结果
//快读模板
inline int read()
{
int x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
//快速幂(用于费马小定理求逆元)
ll fastpow(ll x,ll y)
{
x%=mod;
ll res=1;
while(y)
{
if(y&1) res=res%mod*x%mod;
y>>=1;
x=x*x%mod;
}
return res%mod;
}
//连乘中每一项的值 x为质因数,y为对应质因数的幂次
int solve(int x,int y)
{
int k=0;y=y*b;//每一个质因子的幂次都还要乘以原题中的指数的大小
//特判分母和模数不互质的情况
if((x-1)%mod==0) k=(y+1)%mod;
else k=(fastpow(x%mod,y+1)-1)%mod*fastpow((x-1)%mod,mod-2)%mod;
return k%mod;
}
int main()
{
a=read();b=read();
//底数分解质因子,求其幂次
for(int i=2;i*i<=a;i++){
if(a%i==0)
{
num++;
zyz[num]=i;
mc[num]=1;
a/=i;
while(a%i==0)//还可以继续被这个质因子整除
{
mc[num]++;
a/=i;
}
}
}
if(a!=1)//可能剩余一个很大的质因子数
{
num++;
zyz[num]=a;
mc[num]=1;
}
//连乘
for(int i=1;i<=num;i++)
{
ans=ans*solve(zyz[i],mc[i])%mod;
}
printf("%d\n",(ans%mod+mod)%mod);
return 0;
}
是不是非常友好嘞,觉得友好请来一个友好的赞。觉得不友好的,wa我都wawawawawawawawawawawawawa了卑微(bushi)