洛谷 - P1593 - 因子和 - 费马小定理

类似的因为模数比较小的坑还有卢卡斯定理那道,也是有时候逆元会不存在,因为整除了。使用一些其他方法避免通过逆元。

https://www.luogu.org/fe/problem/P1593

有坑。一定要好好理解费马小定理等逆元存在的条件。费马小定理求逆元的条件是p是质数且a不为0,扩展欧几里得算法的条件是a,m互质。

那么上面用费马小定理求等比数列的分母的逆元的时候,就没有判断a不为0。而他们也不互质所以也不能使用扩展欧几里得算法。

其实当a为0的时候这个退化为等差数列。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; const int mod=9901; ll a,b;
ll factor[100][2];
int ftop=0; void fj() {
for(ll i=2; i*i<=a; i++) {
if(a%i==0) {
ftop++;
factor[ftop][0]=i;
factor[ftop][1]=0;
while(a%i==0) {
factor[ftop][1]++;
a/=i;
}
}
}
if(a!=1) {
ftop++;
factor[ftop][0]=a;
factor[ftop][1]=1;
}
for(int i=1; i<=ftop; i++) {
factor[i][1]*=b;
}
/*for(int i=1; i<=ftop; i++) {
printf("%lld %lld\n",factor[i][0],factor[i][1]);
}*/
} ll da; ll qpow(ll x,ll n) {
x%=mod;
ll res=1;
while(n) {
if(n&1) {
res*=x;
if(res>=mod)
res%=mod;
}
x*=x;
if(x>=mod)
x%=mod;
n>>=1;
}
if(res>=mod)
res%=mod;
return res;
} void calc() {
ll pro=1;
for(int i=1; i<=ftop; i++) {
ll sum=0;
ll &p=factor[i][0];
ll &k=factor[i][1]; if((p-1)%mod==0) {
//退化为等差数列
sum=k+1;
} else {
sum=(qpow(p,k+1)-1+mod)%mod;
//printf("sum=%lld\n",sum);
sum*=qpow(p-1,mod-2);
}
if(sum>=mod)
sum%=mod;
//printf("sum=%lld\n",sum); pro*=sum;
if(pro>=mod)
pro%=mod;
} da=pro%mod;
} int main() {
#ifdef Yinku
freopen("Yinku.in","r",stdin);
#endif // Yinku
scanf("%lld%lld",&a,&b);
if(a==0) {
printf("0\n");
return 0;
}
fj();
calc();
printf("%lld\n",da);
}
上一篇:洛谷 P1593 因子和 题解


下一篇:[洛谷P5075][JSOI2012]分零食