Description has only two Sentences
a
n = X*a
n-1 + Y and Y mod (X-1) = 0.
Your task is to calculate the smallest positive integer k that a k mod a 0 = 0.
Your task is to calculate the smallest positive integer k that a k mod a 0 = 0.
2 0 9
1
推出数列通项:
a(n) = X ^ n * a(0) + X ^ (n - 1) * Y + X ^ (n - 2) * Y + .... + X ^ 1 * Y + X ^ 0 * Y = ( a(0) + Y / (X - 1)) * (X ^ n) - Y / (X - 1)
a(n) % a(0) = 0
(X ^ n - 1) * Y / (X - 1) % a(0) = 0
在a0中除去与Y / (X - 1)共有的约数,剩余的即是X ^ n - 1中应包含的约数
令 b = a(0) / gcd (a(0) , Y / (X - 1))
则有
(X ^ n - 1) % b = 0
X ^ n % b = 1
由欧拉公式得: 若有解,则X与b互素,且n = φ(b)
则解为φ(b)的约数,枚举约数检查上式是否成立
#include<iostream>//(Y/(X-1))*(X^k)%a0=1
#include<cstdio>//X^k%(a0/gcd(a0,n))=1
#include<cmath>//k=phi(a0/gcd(a0,n))
#define max(a,b)(a>b?a:b)
#define min(a,b)(a<b?a:b)
using namespace std;
typedef long long LL;
LL gcd(LL a, LL b){return b==0?a:gcd(b,a%b);}
LL lcm(LL a, LL b){return a%b==0?a:a*b/gcd(a,b);}
LL qmul(LL a, LL b, LL mod){
LL s=1,tmp=a;
while(b){
if(b&1)s=s*tmp%mod;
tmp=tmp*tmp%mod;
b>>=1;
}
return s;
}
LL Euler(LL n){
LL m=(int)sqrt(n+0.5);
LL rt=n;
for(int i=2; i<=m; ++i)if(n%i==0){
rt=rt/i*(i-1);
while(n%i==0)n/=i;
}
if(n>1)rt=rt/n*(n-1);
return rt;
}
int main(){
LL X,Y,a0,k;
while(~scanf("%I64d%I64d%I64d",&X,&Y,&a0)){
if(!Y){printf("1\n");continue;}
LL n=Y/(X-1);
LL gcdna=gcd(max(a0,n),min(a0,n));
a0/=gcdna;
if(gcd(X,a0)!=1){printf("Impossible!\n");continue;}
else k=Euler(a0);
LL m=(LL)sqrt(k+0.5);
bool kk=0;
for(LL i=1; i<=m; ++i)if(k%i==0&&qmul(X,i,a0)==1){
k=i,kk=1;
break;
}
if(!kk){
for(LL i=m; i>=2; --i)if(k%i==0&&qmul(X,k/i,a0)==1){
k=k/i,kk=1;
break;
}
}
printf("%I64d\n",k);
}
return 0;
}