因子和
题目描述
输入两个整数 a和 b,求 aba^bab的因子和。
由于结果太大,只要输出它对 9901 取模的结果。
输入格式
仅一行,为两个整数 a 和 b。
输出格式
输出一行一个整数表示答案对 9901 取模的结果。
输入
2 3
输出
15
数据规模与约定
对于全部的测试点,保证保证 0≤b≤5×10^7 。
首先我们了解一下因子和咋求:
百度百科:算术基本定理,又称为正整数的唯一分解定理,即:每个大于1的自然数均可写为质数的积,而且这些素因子按大小排列之后,写法仅有一种方式。
即任何大于1的整数n可以唯一的表示成
n=p1a1{p_1}^{a_1}p1a1p2a2{p_2}^{a_2}p2a2p3a3{p_3}^{a_3}p3a3p4a4{p_4}^{a_4}p4a4…pnan{p_n}^{a_n}pnan
其因子和为:(p10+p11+p12.....(p_1^0+p_1^1+p_1^2.....(p10+p11+p12.....p1a1){p_1}^{a_1})p1a1)(p20+P21+p22.....(p_2^0+P_2^1+p_2^2.....(p20+P21+p22.....p2a2){p_2}^{a_2})p2a2)…(pn0+pn1+pn2.....(p_n^0+p_n^1+p_n^2.....(pn0+pn1+pn2.....pnan){p_n}^{a_n})pnan)
=∏i=0n\prod \limits_{i=0}^ni=0∏nPiai+1−1pi−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:利用保存的质因子及其幂次,连乘(哦对,中间求逆元的时候还有一个坑,当pip_ipi是质数但是(pi−1)(p_i - 1)(pi−1)的值是取模值的倍数的时候,就不能直接用逆元了,但是pi%modp_i \% modpi%mod目前是等于1啊,也不复杂,即(1+pi1+pi2+⋯+piai)%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)=ai+1a_i+1ai+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)
博客围绕求ab的因子和展开,介绍输入输出格式及数据规模。先阐述因子和的求法,依据算术基本定理,给出因子和公式。接着说明解题思路,先分解质因子及其幂次,再利用其连乘计算,还提及求逆元的特殊情况及取模要求,最后给出完整代码。
1万+

被折叠的 条评论
为什么被折叠?



