hdu1452因子和的积性函数
2015-09-15 00:42
423 查看
s(n)为n的因子和
对于积性函数来说s(2)=1+2=3;s(3)=1+3=4;
那么s(6)=1+2+3+6=12;
所以得到直接给出结论s(a*b)=s(a)*s(b) 且gcd(a,b)=1;
如果p是素数
则s(p^x)=(1+p+p^2+p^3+……+p^x)=(1-p^(x+1))/(1-p);
然后s(2004^x)=((2^(2*x+1)-1)/1 )*((3^(x+1)-1)/2) * ((167^(x+1)-1)/166);
由于167%29=22;
所以s(2004^x)=((2^(2*x+1)-1)/1 )*((3^(x+1)-1)/2) * ((22^(x+1)-1)/21);
又因为(a*b)/c % M =a%M * b%M * inv(c)
又因为 c*inv(c)=1 mod M;
所以 inv(1)=1, inv(2)=15,inv(21)=18;
1*1=1 mod 29, 2*15=1 mod 29, 21 * 18 mod 29;
所以s(2004^x)=((2^(2*x+1)-1) )*((3^(x+1)-1)*15) * ((22^(x+1)-1)*18);
然后就用快速幂和 a ^ b % c=a^(b%euler(c)+euler(c))%c 欧拉函数就可以了吧
euler(29)=28;
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<iostream>
#include<map>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int mod=29;
const int M=28;
int quick_pow(int b,int n){
int a=1;
while(n){
if(n&1) a=(a*b)%mod;
n>>=1;
b=(b*b)%mod;
}
return a;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("1.cpp", "r", stdin);
#endif // ONLINE_JUDGE
int x;
while(scanf("%d",&x)!=EOF&&x!=0){
int a=2*x+1;
int b=x+1;
a=a%M+M;
b=b%M+M;
int x=quick_pow(2,a)-1;
int y=quick_pow(3,b)-1;
int z=quick_pow(22,b)-1;
if(x<0) x+=mod;
if(y<0) y+=mod;
if(z<0) z+=mod;
y*=15;
z*=18;
printf("%d\n",x*y*z%mod);
}
return 0;
}
对于积性函数来说s(2)=1+2=3;s(3)=1+3=4;
那么s(6)=1+2+3+6=12;
所以得到直接给出结论s(a*b)=s(a)*s(b) 且gcd(a,b)=1;
如果p是素数
则s(p^x)=(1+p+p^2+p^3+……+p^x)=(1-p^(x+1))/(1-p);
然后s(2004^x)=((2^(2*x+1)-1)/1 )*((3^(x+1)-1)/2) * ((167^(x+1)-1)/166);
由于167%29=22;
所以s(2004^x)=((2^(2*x+1)-1)/1 )*((3^(x+1)-1)/2) * ((22^(x+1)-1)/21);
又因为(a*b)/c % M =a%M * b%M * inv(c)
又因为 c*inv(c)=1 mod M;
所以 inv(1)=1, inv(2)=15,inv(21)=18;
1*1=1 mod 29, 2*15=1 mod 29, 21 * 18 mod 29;
所以s(2004^x)=((2^(2*x+1)-1) )*((3^(x+1)-1)*15) * ((22^(x+1)-1)*18);
然后就用快速幂和 a ^ b % c=a^(b%euler(c)+euler(c))%c 欧拉函数就可以了吧
euler(29)=28;
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<iostream>
#include<map>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int mod=29;
const int M=28;
int quick_pow(int b,int n){
int a=1;
while(n){
if(n&1) a=(a*b)%mod;
n>>=1;
b=(b*b)%mod;
}
return a;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("1.cpp", "r", stdin);
#endif // ONLINE_JUDGE
int x;
while(scanf("%d",&x)!=EOF&&x!=0){
int a=2*x+1;
int b=x+1;
a=a%M+M;
b=b%M+M;
int x=quick_pow(2,a)-1;
int y=quick_pow(3,b)-1;
int z=quick_pow(22,b)-1;
if(x<0) x+=mod;
if(y<0) y+=mod;
if(z<0) z+=mod;
y*=15;
z*=18;
printf("%d\n",x*y*z%mod);
}
return 0;
}