题意:
求2004的x次方的所有因子的和,结果对29取余。
思路:
还是这个公式,2004=2^2*3*167
因此sigam(n)=(2^(2*x+1)-1)*(3^(x-1)-1)/2*(167^(x+1)-1)/166
因为167%29=22,可以结果可简化为:
ans=((2^(2*x+1)-1)*(3^(x-1)-1)/2*(22^(x+1)-1)/21)%29
对于幂次方用快速幂求解,当然取模后不一定能整除2和21,于是用对于29的逆元15与18代替,15*18%29=9
最终式为ans=((2^(2*x+1)-1)*(3^(x-1)-1)*(22^(x+1)-1))*9%29
#include <iostream>
#include <stdio.h>
using namespace std;
int exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
else
{
int r=exgcd(b,a%b,y,x);
y-=x*(a/b);
return r;
}
}
void ss()
{
int x,y;
exgcd(2,29,x,y);
if(x<0) x+=29;
cout<<x<<endl;
exgcd(21,29,x,y);
if(x<0) x+=29;
cout<<x<<endl;
}
long long powmod(long long a,long long i,long long n)
{
if(i==0)
return 1%n;
int temp=powmod(a,i>>1,n);
temp=temp*temp%n;
if(i&1)
temp=(long long)temp*a%n;
return temp;
}
long long res(long long a)
{
a--;
if(a>=0)
return a;
else
return a+29;
}
int main()
{
int n;
//ss();
while(cin>>n)
{
if(n==0) break;
int a=(2*n+1)%28;
int b=(n+1)%28;
cout<<(res(powmod(2,a,29))*res(powmod(3,b,29))*res(powmod(22,b,29))*9)%29<<endl;
}
return 0;
}
//2*2*3*167
//((2^(2*n+1)-1)%29*(3^(n+1)-1/2)%29*(22^(n+1)-1/21)%29)%29
//((2^(2*n+1)-1)*(3^(n+1)-1)*15*(22^(n+1)-1/21)*18)%29