题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1452
题意:
输入一个数X,求2004^X的所有因子对29取余。。
思路:
首先我们来看:
因子和
6的因子是1,2,3,6;6的因子和是 s(6)=1+2+3+6=12;
20的因子是1,2,4,5,10,20;20的因子和是 s(20)=1+2+4+5+10+20=42;
2的因子是1,2;2的因子和是 s(2)=1+2=3;
3的因子是1,3;3的因子和是 s(3)=1+3=4;
4的因子和是 s(4)=1+2+4=7;
5的因子和是 s(5)=1+5=6;
s(6)=s(2)*s(3)=3*4=12;
s(20)=s(4)*s(5)=7*6=42;
再看 s(50)= 1+2+5+10+25+50=93=3*31=s(2)*s(25),s(25)=1+5+25=31.
这在数论中叫积性函数,当gcd(a,b)=1时 s(a*b)=s(a)*s(b);
如果p是素数
s(p^n)=1+p+p^2+...+p^n= (p^(n+1)-1) /(p-1)了解了这一点我们就有s(2004)=s(2^2)*s(3)*s(167)
那么 s(2004^x)=s(2^(2x))*s(3^x)*s(167^x),因为2,3,167都是素数则有
t1=(2^(2x+1)-1)%29
t2=((3^(x+1)-1)/2)%29
t3=((167^(x+1)-1)/166)%29
根据乘法逆元,t2=((3^(x+1)-1)*15)%29 t3=((167^(x+1)-1)*18)%29
PS:乘法逆元就是a*b对于某个数取余和1对这个数取余是相同的
ans=t1*t2*t3%29
代码:
#include<stdio.h>
#include<string.h>
int pow_mod(int a,int b,int c)
{
if(b==0)
return 1;
int x=pow_mod(a,b/2,c);
int ans=x*x%c;
if(b&1)
ans=ans*a%c;
return ans;
}
int main()
{
int x;
while(scanf("%d",&x),x)
{
int t1=pow_mod(2,2*x+1,29);
int t2=pow_mod(3,x+1,29);
int t3=pow_mod(167,x+1,29);
//printf("%d %d %d\n",t1,t2,t3);
int ans=(t1-1)*(t2-1)*15*(t3-1)*18%29;
printf("%d\n",ans%29);
}
return 0;
}
代码: