题目大意是让你求2004的X次方的所有因子之和。
很明显遇到所谓的求什么因子啦,倍数啥的一般都是用数论问题解决。
一个数的因子和是一个积性函数
关于积性函数,即F(ab)=F(a)*F(b),在数论里有很多积性函数
来证明一下:
S(x)表示x的因子和。
如果x可以分成a,b(一定为素数),那么S(x)=S(a)*S(b)。
为什么一定要分成素数呢,因为一个素数的因子之后1和它本身,对于a,b 来说,就是1,a,1,b,那么x=a*b,x的因子只有1,a,,b,x这四个数,
(1+a)*(1+b)=1+a+b+a*b。看明白了么,这就是所谓的一个数的因子和是一个积性函数。
则题目求为:S(2004^X)mod 29
那么可以知道:2004=4 * 3 *167
S(2004^X)=S(2^(2X)) * S(3^X) * S(167^X)
如果 p 是素数 则其因子只有1和它本身,S(p^X)=1+p+p^2+...+p^X = (p^(X+1)-1)/(p-1)
所以:S(2004^X)=(2^(2X+1)-1) * (3^(X+1)-1)/2 * (167^(X+1)-1)/166
考虑到 167%29 == 22
原式可写为 S(2004^X)=(2^(2X+1)-1) * (3^(X+1)-1)/2 * (22^(X+1)-1)/21
(a*b)/c %M= a%M * b%M * inv(c)
其中inv(c)即满足 (c*inv(c))%M=1的最小整数,用术语讲,inv(c)表示c在模p下的乘法逆元
这里M=29 则inv(1)=1,inv(2)=15,inv(22)=15
原式可写为: S(2004^X)=(2^(2X+1)-1) * (3^(X+1)-1)/2 * (22^(X+1)-1)/21
=(2^(2X+1)-1) * (3^(X+1)-1)*15 * (22^(X+1)-1)*18
进一步15*18%29=9;
所以就是求 : (2^(2X+1)-1) * (3^(X+1)-1)* (22^(X+1)-1)*9%29;
代码:
#include<cstdio>
#include<iostream>
using namespace std;
int power(int a,int b,int c) { //a的b次方对c取模
int res=1;
while(b) {
if(b&1)
res=res*a%c;
a=a*a%c;
b>>=1;
}
--res;
return res<0?res+c:res;
}
int main()
{
int x,a,b;
while(cin>>x&&x)
{
a=(2*x+1)%28;
b=(x+1)%28;
cout<<9*power(2,a,29)*power(3,b,29)*power(22,b,29)%29<<endl;
}
}