2004 = 2^2*3*167
2004^x = 2^2*x*3^x*167^x
sum(x) 表示 x 的因子和则有 sum(2004^x) %29 = (2^2*x)%29*(3^x)%29*(167^x)%29
∵ 167 % 29 = 22
∴ sum(2004^x)%29 = (2^2*x)%29*(3^x)%29*(22^x)%29
=sum(2^2*x)%29*sum(3^x)%29*sum(22^x)%29
又已知 若p为素数 sum(p^n) = 1+p+p^2+...+p^n = (p^(n+1)-1) /(p-1) (等比数列求和)
∴ 设 a = sum(2^2*x)%29
b = sum(3^x)%29
c = sum(22^x)%29
由上述式子可得
a = (2^(2*x+1)-1)%29
b = (3^(x+1)-1)/2%29
c = (22^(x+1)-1)/21 %29
又有 模运算法则 乘法法则 (a*b)%MOD = (a%MOD*b%MOD)%MOD
除法法则 (a/b)%MOD = (a*b^(-1)%MOD)
∴ sum(2004^x)%29 = (2^(2*x+1)-1)%29 * [(3^(x+1)-1)/2]%29*[(22^(x+1)-1)/21]%29
= (2^(2*x+1)-1)%29 *[(3^(x+1)-1)*2^(-1)%29]*[(22^(x+1)-1)*21^(-1)%29]
这里的 b^(-1) 是b的逆元素(%MOD)
2的逆元是15 2*15 = 30%29 = 1
21的逆元是18 21*18 = 378%29 = 1
(即下面所说的inv 满足该条件 c*inv(c)%MOD = 1 最小的)
又∵ (a*b)/c%MOD = a%MOD*b%MOD*inv(c)
c*inv(c)%MOD = 1 inv(c)是所有满足上式中最小的
inv(2) = 15, inv(21) = 18
∴ sum(2004^x)%29 = ((2^(2*x+1)-1)*(3^(x+1)-1)*15*(22^(x+1)-1)*18)%29
a = (2^(2*x+1)-1)%29
b = (3^(x+1)-1)*15%29
c = (22^(x+1)-1)*18%29
sum(2004^x)%29 = (a*b)%29*c%29
接下来用快速幂就可以解决咯啊~
快速幂 传送门
#include <iostream>
#include <cstdlib>
using namespace std;
typedef long long LL;
LL quick_mod(LL a,LL b)
{
LL ans = 1;
while(b)
{
if(b&1) ans=ans*a%29;
b>>=1;
a=a*a%29;
}
return ans ;
}
int main()
{
LL x,a,b,c;
while(cin>>x&&x)
{
a = (quick_mod(2,2*x+1)-1)%29;
b = (quick_mod(3,x+1)-1)*15%29;
c = (quick_mod(22,x+1)-1)*18%29;
cout<<(a*b)%29*c%29<<endl;
}
return 0;
}
研究了好长时间 找各路大牛的代码 又添加了些自己的理解才弄得差不多了这道题~