洛谷 P2715 约数和
给出a和b求a^b的约数和。
题目描述
输入输出格式
输入格式:
一行两个数a,b。
输出格式:
一个数表示结果对 9901 的模。
输入输出样例
输入样例#1:
2 3
输出样例#1:
15
说明
对于 30%的数据,a,b≤ 10 对于 100%的数据,0 ≤ a,b ≤ 50 000 000
早上听大爷讲完数论马上回来补了一道
这题呢 我们首先可以吧a质因数分解 表示为p1^c1 × p2^c2 ×……× pn^cn
那么a^b就可以表示为p1^(c1*B) × p2^(c2*B) ×……× pn^(cn*B)
A^B的约数表示为p1^k1 × p2^k2 ×……× pn^kn,其中0<=ki<=ci*B
那么所有的约数和就是(1+p1+p1^2+……+p1^(c1*B)) × (1+p2+p2^2+……+p2^(c2*B)) ×……× (1+pn+pn^2+……+pn^(cn*B))
这个拿乘法定律什么的搞一下就可以得到了哇
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int mod=9901; LL read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } LL n,m,ans=1; LL sum[255],h[255],cnt; LL qmod(LL a,LL b){ LL ans=1; while(b){ if(b&1) ans=ans*a%mod; b>>=1; a=a*a%mod; } return ans; } void prepare(){ LL v=n; for(int i=2;i<=v;i++)if(n%i==0){ sum[++cnt]=i; h[cnt]++; n/=i; while(n%i==0) h[cnt]++,n/=i; h[cnt]*=m; if(!n) return ; } } int main() { n=read(); m=read(); prepare(); //for(int i=1;i<=cnt;i++) printf("[%lld %lld]\n",sum[i],h[i]); for(int i=1;i<=cnt;i++){ LL q=qmod(sum[i]-1,mod-2),p=qmod(sum[i],h[i]+1)-1; ans=ans*p%mod*q%mod; }printf("%lld\n",ans); return 0; }