题意:
给你三个数
,且
让你求一个最小的
,使得
,若不存在输出Impossible!。
思路:
首先我们要找到
与
的关系。
有以上递推式可得
根据题意有
即
即
令
那么有
因
与 互质
所以有
令
有
即
显然上述模线性方程有整数解当且仅当
接下来 寻找最小的
有一个结论是:
若存在
满足上述模线性方程,那么有
,即
为
的因子,所以我们只需要在
的因子里验证一下是否存在最小的
即可。
注意当
时,
显然成立,特判一下
上面推导过程是一般的流程,我因为忘了有 这个条件,所以可能较麻烦,各位看官可以自己加上这个条件自己推一下,似乎就不用特判 时了。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<map>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 2e6;
ll phi(ll n){
ll ans = n;
for(ll i = 2;i <= sqrt(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 Qpow(ll a,ll b,ll p){
ll ans = 1;
// a %= p;
while(b){
if(b&1) ans = ans * a % p;
b >>= 1;
a = a * a % p;
}
return ans;
}
int main(){
ll x,y,a0;
while(cin>>x>>y>>a0){
if(y == 0) {
puts("1");
continue;
}
ll d = __gcd((x-1)*a0,y);
ll k = (x-1)*a0/d;
if(__gcd(x,k) != 1) puts("Impossible!");
else {
ll a = phi(k);
ll ans = (ll)1e16;
if(Qpow(x,a,k) == 1) ans = a;
for(ll i = 1;i <= sqrt(a);++i){
if(a % i == 0){
if(Qpow(x,i,k) == 1) ans = min(ans,i);
if(Qpow(x,a/i,k) == 1) ans = min(ans,a/i);
}
}
if(ans == (ll)1e16) puts("Impossible!");
else cout<<ans<<endl;
}
}
}