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.
Input
Each line will contain only three integers X, Y, a 0 ( 1 < X < 2 31, 0 <= Y < 2 63, 0 < a 0 < 2 31).
Output
For each case, output the answer in one line, if there is no such k, output “Impossible!”.
Sample Input
2 0 9
Sample Output
1
题意:
题目给你三个数 X,Y,a0 X , Y , a 0 我们知道了一个等式, an=X∗an−1+Y a n = X ∗ a n − 1 + Y 并且 Y mod (X−1)==0 Y m o d ( X − 1 ) == 0 让我们求一个最小的k使得 ak % a0=0 a k % a 0 = 0
分析:
我们先把每个式子写出了观察一下规律
a0=a0 a 0 = a 0
a1=Xa0+Y a 1 = X a 0 + Y
a2=Xa1+Y=X(Xa0+Y)+Y=X2a0+XY+Y a 2 = X a 1 + Y = X ( X a 0 + Y ) + Y = X 2 a 0 + X Y + Y
a3=Xa2+Y=X(X2a0+XY+Y)+Y=X3a0+X2Y+XY+Y
a
3
=
X
a
2
+
Y
=
X
(
X
2
a
0
+
X
Y
+
Y
)
+
Y
=
X
3
a
0
+
X
2
Y
+
X
Y
+
Y
.
.
.
an=Xan−1+Y=Xna0+Xn−1Y+Xn−2Y+⋯+XY+Y
a
n
=
X
a
n
−
1
+
Y
=
X
n
a
0
+
X
n
−
1
Y
+
X
n
−
2
Y
+
⋯
+
X
Y
+
Y
=Xna0+Y(1+X+X2+X3+⋯+Xn−1)
=
X
n
a
0
+
Y
(
1
+
X
+
X
2
+
X
3
+
⋯
+
X
n
−
1
)
=Xna0+Y⋅Xn−1X−1
=
X
n
a
0
+
Y
⋅
X
n
−
1
X
−
1
因此我们发现了通项公式
ak=Xka0+Y⋅Xk−1X−1 a k = X k a 0 + Y ⋅ X k − 1 X − 1
所以
ak % a0=Y⋅Xk−1X−1 % a0=0 a k % a 0 = Y ⋅ X k − 1 X − 1 % a 0 = 0
因此我们得到
a0 | YX−1⋅(Xk−1) a 0 | Y X − 1 ⋅ ( X k − 1 )
我们设 d=gcd(a0,YX−1) d = g c d ( a 0 , Y X − 1 )
则
a0d | YX−1d⋅(Xk−1) a 0 d | Y X − 1 d ⋅ ( X k − 1 )
很明显 a0d和 a 0 d 和 YX−1d Y X − 1 d 是互质的
那么有
a0d | (Xk−1) a 0 d | ( X k − 1 )
写成同余式的形式为
Xk≡1 (mod a0d) X k ≡ 1 ( m o d a 0 d )
那么需要用到欧拉定理和The Luckiest number POJ3696这个题一模一样了
code:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
ll X,Y,a0;
ll mul(ll a,ll b,ll mod){
ll ans = 0;
while(b){
if(b & 1)
ans = (ans + a) % mod;
a = (a + a) % mod;
b >>= 1;
}
return ans;
}
ll q_pow(ll a,ll b,ll mod){
ll ans = 1;
while(b){
if(b & 1)
ans = mul(ans,a,mod);
a = mul(a,a,mod);
b >>= 1;
}
return ans;
}
ll Euler(ll n){
ll ans = n;
for(ll i = 2; i * i <= n; i++){
if(n % i == 0){
ans = ans / i * (i - 1);
while(n % i == 0) n /= i;
}
}
if(n > 1) ans = ans / n * (n - 1);
return ans;
}
ll gcd(ll a,ll b){
return b ? gcd(b,a%b) : a;
}
int main(){
while(~scanf("%lld%lld%lld",&X,&Y,&a0)){
ll p = a0 / gcd(a0,Y/(X-1));
ll d = gcd(X,p);
if(d != 1){
printf("Impossible!\n");
}
else{
ll phi = Euler(p);
ll ans = phi;
ll m = sqrt((double)phi);
bool flag = false;
for(ll i = 1; i <= m; i++){
if(phi % i == 0 && q_pow(X,i,p) == 1){
ans = i;
flag = true;
break;
}
}
if(!flag){
for(ll i = m; i >= 2; i--){
if(phi % i == 0 && q_pow(X,phi/i,p) == 1){
ans = phi / i;
break;
}
}
}
printf("%lld\n",ans);
}
}
return 0;
}