Happy 2004
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1413 Accepted Submission(s): 1029
Problem Description
Consider a positive integer X,and let S be the sum of all positive integer divisors of 2004^X. Your job is to determine S modulo 29 (the rest of the division of S by 29).
Take X = 1 for an example. The positive integer divisors of 2004^1 are 1, 2, 3, 4, 6, 12, 167, 334, 501, 668, 1002 and 2004. Therefore S = 4704 and S modulo 29 is equal to 6.
Take X = 1 for an example. The positive integer divisors of 2004^1 are 1, 2, 3, 4, 6, 12, 167, 334, 501, 668, 1002 and 2004. Therefore S = 4704 and S modulo 29 is equal to 6.
Input
The input consists of several test cases. Each test case contains a line with the integer X (1 <= X <= 10000000).
A test case of X = 0 indicates the end of input, and should not be processed.
A test case of X = 0 indicates the end of input, and should not be processed.
Output
For each test case, in a separate line, please output the result of S modulo 29.
Sample Input
1 10000 0
Sample Output
6 10
思路:将2004分解质因子,并分别将指数乘以x即可得到公式,我们知道x=p1的e1次方*p2的e2次方*p3的e3次方...*pk的ek次方(p均为质数,e均为整数)
那么因子和为(1+p1+p1的2次方+...p1的e1次方)*...*(1+pk+pk的2次方+...pk的ek次方)
而1+p1+p1的2次方+...p1的e1次方=(p1的(e1+1)次方-1)/(p1-1) 因为此处需要取模,所以需要对p1-1用乘法逆元
代码一:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define mod 29
int e[10][2];
int cnt;
void devide(int n)
{
cnt=0;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
{
int num=0;
while(n%i==0)
{
num++;
n/=i;
}
e[++cnt][0]=i,e[cnt][1]=num;
}
}
if(n>1) e[++cnt][0]=n,e[cnt][1]=1;
}
int pow_mod(int a,int n)
{
int ans=1;
while(n)
{
if(n&1) ans=ans*a%mod;
a=a*a%mod;
n/=2;
}
return ans;
}
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
int extend_gcd(int a,int b,int &x,int &y)
{
if(!b)
{
x=1,y=0;
return a;
}
int x1=x,y1=y;
int d=extend_gcd(b,a%b,x1,y1);
x=y1;
y=x1+(a/b)*y1;
return d;
}
int mod_reverse(int a,int n)
{
int x,y;
int d=extend_gcd(a,n,x,y);
if(d!=1) return -1;
return (x%n+n)%n;
}
int main()
{
int x;
devide(2004);
while(~scanf("%d",&x)&&x)
{
int ans=1;
for(int i=1;i<=cnt;i++)
{
int inv=mod_reverse(e[i][0]-1,mod);
ans=(ans*(pow_mod(e[i][0],e[i][1]*x+1)-1)%mod*inv)%mod;
}
printf("%d\n",ans);
}
return 0;
}
或者可以用公式x/d%k==x%(d*k)/d这样就可以直接得到答案了。注意取模就要全部都对(d*k)取了~
代码二
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define LL long long
#define N 10000010
LL pow_mod(LL a,LL n,int mod)
{
LL ans =1;
while(n)
{
if(n&1) ans=ans*a%mod;
a=a*a%mod;
n>>=1;
}
return ans;
}
int main()
{
LL T,x;
while(scanf("%lld",&x)&&x)
{
LL temp2=pow_mod(2,2*x+1,29*332)-1;
LL temp3=pow_mod(3,x+1,29*332)-1;
LL temp167=pow_mod(167,x+1,29*332)-1;
LL ans=temp2*temp3*temp167%(29*332)/332;
printf("%lld\n",ans);
}
return 0;
}