分析:
1:
因子和 是 积性函数S(x) ,即 gcd(a , b ) =1 则 S(a* b )= S(a) * S(b)
因子个数 也是积性函数 f(x)
故有 S(2004) = S(2^2) * S(3) * S (167)
S(2004 ^n) mod 29= S (2 ^ 2*n)mod 29 * S (3 ^n) mod 29 * S(167 ^n) mod 29
= S (2 ^ 2*n)mod 29 * S (3 ^n) mod 29 * S(22 ^n) mod 29
2:
p是素数 ,
则 S(p^n) = 1+ p +……+p^n= (p^(n+1) -1) / (p-1)
S(P^n) mod 29 = (p^(n+1) -1) mod 29 / (p-1) (mod 29) = (p^(n+1) -1) mod 29 * (p-1) ^(-1) (mod 29)
从这个式子,我们需要计算 (p-1) mod 29 的逆元, (p-1) ^(-1) (mod 29), 同时也需要计算 p^(n+1) 故我们需要用到快速幂乘
代码如下:
#include<iostream> #include<stdlib.h> #include<stdio.h> #include<math.h> #include<string.h> #include<string> #include<queue> #include<algorithm> #include<map> #define Mod 29 using namespace std; //快速求幂 a^b %n int mod_exp(int a,int b,int n) { int t=1; for(;b>0; b>>=1 , a=(a*a)%n) if(b&1) t=(t*a)%n; return t; } // 扩展 欧几里得 求最大公约数 // 返回d= gcd(a,b) 和 对应于等式 ax + by =d 中的x ,y int extend_gcd(int a, int b, int &x , int &y) { if(b==0 && a==0) return -1; // 无最大公约数 if(b==0){x=1; y=0; return a;} int d=extend_gcd(b, a%b , y, x); y-= a/b *x; return d; } // ***************求逆元素********** // ax= 1(mod n) int mod_reverse(int a, int n) { int x,y; int d=extend_gcd(a,n,x,y); if(d==1) return (x%n +n)%n; else return -1; } int main() { int n; int a,b,c; while(scanf("%d",&n)&&n) { a=(mod_exp(2,2*n+1,Mod)-1)*mod_reverse(2-1,Mod); b=(mod_exp(3,n+1,Mod)-1)*mod_reverse(3-1,Mod); c=(mod_exp(22,n+1,Mod)-1)*mod_reverse(22-1, Mod); printf("%d ",a*b*c%Mod); } return 0; }