唯一分解:
n=p1k2p1k2…pmkm
因子数:
n的因子数即n的因子个数
考虑n的每个质因子pk,因为在n的因子中p出现的次数有0到k这k+1种可能,则:
因子数=(k1+1)(k2+1)(k3+1)…(km+1)
因子和:
n的因子和即n的所有因子的和
因子和=(1+p1+p12+…p1k1)(1+p2+p22+…p2k2)…(1+pm+pm2+…pmkm)
可以用牛顿二项式证明。
把里面的每一个乘积项用等比数列转换一下,则:
因子和=[(p1k1+1-1)/(p1-1)]…[(pmkm+1-1)/(pm-1)]
hdu1215 七夕节
题意:
给定n,计算n的因子和(n本身不算在内)
code:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int ppow(int a,int b){
int ans=1;
while(b){
if(b&1){
ans=ans*a;
}
a=a*a;
b>>=1;
}
return ans;
}
int cal(int p,int k){
return (ppow(p,k+1)-1)/(p-1);
}
signed main(){
int T;
cin>>T;
while(T--){
int n;
cin>>n;
int nn=n;
int ans=1;
for(int i=2;i*i<=n;i++){
if(n%i==0){
int cnt=0;
while(n%i==0)n/=i,cnt++;
ans*=cal(i,cnt);
}
}
if(n!=1)ans*=cal(n,1);
ans-=nn;//不包括自己,所以减掉
cout<<ans<<endl;
}
return 0;
}
hdu1452 Happy 2004
题意:
给定x,要求计算出2004x的因子和对29取模的结果
思路:
2004=22311671
2004x=22x3x167x
直接计算因子和就行了,因子和里面的除法改成乘法逆元
code:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod=29;
int ppow(int a,int b,int mod){
int ans=1;
while(b){
if(b&1){
ans=ans*a%mod;
}
a=a*a%mod;
b>>=1;
}
return ans;
}
int cal(int p,int k){
return (ppow(p,k+1,mod)-1+mod)%mod*ppow(p-1,mod-2,mod)%mod;
}
signed main(){
int x;
while(cin>>x){
if(!x)break;
int ans=cal(2,2*x)*cal(3,x)%mod*cal(167,x)%mod;
cout<<ans<<endl;
}
return 0;
}