X^Y mod Z = K 给出X、Y、Z,我们都知道如何很快的计算K。但是如果给出X、Z、K,你是否知道如何快速的计算Y呢?
x,z不互质:exBSGS
详见:https://blog.csdn.net/ww140142/article/details/47837521
x,z互质,用exgcd求逆元
关于逆元的几种求法和运用:
https://blog.csdn.net/acdreamers/article/details/8220787(例题)
https://blog.csdn.net/guhaiteng/article/details/52123385
数学题一定要先推清楚式子再写
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#include<cmath>
using namespace std;
typedef long long ll;
ll x,y,z,k,inv;
map <int,int> mp;
ll log_(ll x){
return (ll)(log(x) / log(2));
}
ll gcd(ll x,ll y){
if ( !y ) return x;
return gcd(y,x % y);
}
ll power(ll x,int y){
ll res = 1;
while ( y ){
if ( y & 1 ) res = res * x % z;
x = x * x % z;
y >>= 1;
}
return res;
}
void exgcd(ll x,ll z,ll &a,ll & b){
if ( !z ){
a = 1 , b = 0;
return;
}
exgcd(z,x % z,a,b);
ll t = a;
a = b , b = t - x / z * b;
}
ll getinv(ll x,ll z){
ll a,b;
exgcd(x,z,a,b);
return (a % z + z) % z;
}
int BSGS(ll a,ll b){
int sz = (int)sqrt(z) + 1; ll x = b;
for (int i = 0 ; i <= sz ; i++){
if ( !mp[x] ) mp[x] = i + 1;
x = x * inv % z;
}
if ( mp[1] ) return mp[1] - 1;
a = power(a,sz) , x = 1;
for (int i = 1 ; i <= z / sz + 1 ; i++){
x = x * a % z;
if ( mp[x] ) return mp[x] + sz * i - 1;
}
return -1;
}
int check(){
ll cur = x % z;
for (int i = 1 ; i <= log_(z) + 1 ; i++){
if ( cur == k ) return i - 1;
cur = cur * x % z;
}
int cnt = 0; ll d = gcd(x,z),p = d;
while ( d != 1 ){
cnt++ , z /= d;
d = gcd(x,z) , p = p * d;
}
if ( k % p != 0 ) return -1;
inv = getinv(x,z);
k = k * power(inv,cnt) % z;
int ans = BSGS(x,k);
if ( ans == -1 ) return -1;
return ans + cnt;
}
int main(){
freopen("input.txt","r",stdin);
while ( 1 ){
cin>>x>>z>>k;
if ( !x && !z && !k ) break;
mp.clear();
int d = check();
if ( d != -1 ) printf("%d\n",d);
else printf("No Solution\n");
}
return 0;
}