这道题运用到积性函数
先介绍下积性函数及其性质:
在数论中的积性函数:对于正整数n的一个算术函数 f(n),若f(1)=1,且当a,b互质时f(ab)=f(a)f(b),在数论上就称它为积性函数。若对于某积性函数 f(n) ,就算a, b不互质,也有f(ab)=f(a)f(b),则称它为完全积性的
对于积性函数有如下性质:
而某个数的所有因子之和对应的函数恰为积性函数,这点记住就好,至于为什么感觉如果不是专业学这个的就不必要深究了,那么我们定义f(n)为n的所有因子之和,则对于该题f(2004) = f(2^2)*f(3)*f(167)//素数打下表可以得到
那么f(p1^a1)在p1为素数时等于什么呢?
很容易知道p1^a1的因子为1 p1 p1^2 ... p1^a1
所以其和为(p^(a1+1)-1)/(p-1)//等比序列求和
于是
f(2004^k)%29 = f(2^(2*k)) * f(3^k) * f(167^k)%29
=(2^(2*k+1)-1) * ((3^(k+1)-1)/2) * ((167^(k+1)-1)/166) % 29
根据同余方程:若a = b % m 则a^k = b^k % m
结合(a ± b) % m = a%m ± b%m
所以原式=(2^(2*k+1)-1) * ((3^(k+1)-1)/2) * ((22^(k+1)-1)/21) % 29
再结合公式:
(a*b) % m = a%m * b%m
(a/b) % m = (a * b^(-1))%m
b与b^(-1)关于m互逆,即b * b^(-1) %m = 1(b^(-1)为整数)
对应扩展欧几里得方程b*x = 1(mod m) 解出b即为b^-1
因为这里只需要求2和166的逆,直接找出即可,没有写扩展欧几里得的必要
很容易得到
2的逆元素是15,因为2*15=30 % 29=1 % 29
21的逆元素是18,因为21*18=378% 29 =1 % 29
所以计算下式即可:
a=(pow(2,2*x+1,29)-1)% 29;
b=(pow(3,x+1,29)-1)*15 % 29;
c=(pow(22,x+1,29)-1)*18 % 29;
ans=(a*b)% 29*c % 29;
再写一个快速幂即可!
代码如下:
#include <math.h>
#include <stdio.h>
int Pow(int a, int b, int c) {
int ans = 1;
while(b) {
if(b & 1)
ans = ans%c*(a%c)%c;
a = a%c*a%c;
b >>= 1;
}
return ans;
}
int main(void) {
int n, c1, c2, c3;
while(scanf("%d", &n), n) {
c1 = Pow(2, 2*n+1, 29)-1;
c2 = (Pow(3, n+1, 29)-1)*15%29;
c3 = (Pow(22, n+1, 29)-1)*18%29;
printf("%d\n", c1*c2%29*c3%29);
}
return 0;
}