唯一分解:
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;
}