http://hi.baidu.com/aekdycoin/item/236937318413c680c2cf29d4 这里已经说的很清楚了
A^X = B MOD(C) 若 gcd(A,C)!=1 令 d = gcd(A,C) B/=d, C/=d 重复此过程 我们得到 d1,d2,d3,d4...............dk;
我们得到 令 P = d1*d2*d3.......*dk; A'=A^k/P, B‘=B/P C' = C/P; A^(X-k)*A' = B' mod( C' ) 此为 已经是 普通情况的 BABY STEP 了
HDU 2815
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<numeric>
#include<vector>
#include<string>
#include<set>
#include<iostream>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 71111;
const int mod = 77777;
const int hash_size = 87719;
template<typename T>
T gcd(T a,T b)
{
return b?gcd(b,a%b):a;
}
struct node {
ll key;
int val, next;
node() {
}
node(ll key, int val, int next) :
key(key), val(val), next(next) {
}
};
struct HashMap {
node edge[hash_size << 2];
int i, E;
int head[hash_size + 10];
void init() {
E = 0;
memset(head, -1, sizeof(head));
}
bool insert(ll key, int val) {
int u;
u = key % hash_size;
for (i = head[u]; ~i; i = edge[i].next) {
if (edge[i].key == key)
return false;
}
edge[E] = node(key, val, head[u]);
head[u] = E++;
return true;
}
int find(ll key) {
int u = key % hash_size;
for (i = head[u]; ~i; i = edge[i].next) {
if (edge[i].key == key)
return edge[i].val;
}
return -1;
}
};
HashMap Hash;
ll exgcd(ll a, ll b, ll &x, ll &y) {
if (!b) {
x = 1;
y = 0;
return a;
}
ll d = exgcd(b, a % b, x, y);
ll t = x;
x = y;
y = t - (a / b) * y;
return d;
}
ll remain[100];
ll go(ll A, ll B, ll C) {
if(B>=C) return -1;
if(B==1) return 0;
ll D=1,d,t=1;
int i,cnt=0;
for(i=0;i<=100;t=t*A%C,++i)
{
if(t==B) return i;
}
while((d=gcd(A,C))!=1)
{
if(B%d) return -1;
cnt++;
B/=d;
C/=d;
D=D*(A/d)%C;
}
int m=(int)ceil(sqrt(C+0.0));
//map<ll,int>mp;
t=1;
Hash.init();
for(i=1;i<=m;++i)
{
t=t*A%C;
Hash.insert(t,i);
}
ll x,y;
//cout<<A<<" "<<B<<" "<<C<<endl;
for(i=0;i<=m;D=D*t%C,++i)
{
exgcd(D,C,x,y);
x*=B;
x=(x%C+C)%C;
y=Hash.find(x);
if(~y)
return 1ll*i*m+y+cnt;
}
return -1;
}
int main() {
ios::sync_with_stdio(false);
ll K, P, N;
//freopen("D:\\test.in","r",stdin);
//freopen("D:\\test1.in","w",stdout);
while (~scanf("%I64d%I64d%I64d", &K, &P, &N)) {
ll ans=go(K,N,P);
if (~ans)
printf("%I64d\n", ans);
else
puts("Orz,I can’t find D!");
}
return 0;
}
poj 3243
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<numeric>
#include<vector>
#include<string>
#include<set>
#include<iostream>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 71111;
const int mod = 77777;
const int hash_size = 87719;
template<typename T>
T gcd(T a, T b) {
return b ? gcd(b, a % b) : a;
}
struct node {
ll key;
int val, next;
node() {
}
node(ll key, int val, int next) :
key(key), val(val), next(next) {
}
};
struct HashMap {
node edge[hash_size << 2];
int i, E;
int head[hash_size + 10];
void init() {
E = 0;
memset(head, -1, sizeof(head));
}
bool insert(ll key, int val) {
int u;
u = key % hash_size;
for (i = head[u]; ~i; i = edge[i].next) {
if (edge[i].key == key)
return false;
}
edge[E] = node(key, val, head[u]);
head[u] = E++;
return true;
}
int find(ll key) {
int u = key % hash_size;
for (i = head[u]; ~i; i = edge[i].next) {
if (edge[i].key == key)
return edge[i].val;
}
return -1;
}
};
HashMap Hash;
ll exgcd(ll a, ll b, ll &x, ll &y) {
if (!b) {
x = 1;
y = 0;
return a;
}
ll d = exgcd(b, a % b, x, y);
ll t = x;
x = y;
y = t - (a / b) * y;
return d;
}
ll remain[100];
ll go(ll A, ll B, ll C) {
if (B >= C)
B%=C;
if (B == 1)
return 0;
ll D = 1, d, t = 1;
int i, cnt = 0;
for (i = 0; i <= 100; t = t * A % C, ++i) {
if (t == B)
return i;
}
while ((d = gcd(A, C)) != 1) {
if (B % d)
return -1;
cnt++;
B /= d;
C /= d;
D = D * (A / d) % C;
}
int m = (int) ceil(sqrt(C + 0.0));
//map<ll,int>mp;
t = 1;
Hash.init();
for (i = 1; i <= m; ++i) {
t = t * A % C;
Hash.insert(t, i);
}
ll x, y;
for (i = 0; i <= m; D = D * t % C, ++i) {
exgcd(D, C, x, y);
x *= B;
x = (x % C + C) % C;
y = Hash.find(x);
if (~y)
return 1ll * i * m + y + cnt;
}
return -1;
}
int main() {
ios::sync_with_stdio(false);
ll K, P, N;
while (~scanf("%I64d%I64d%I64d", &K, &P, &N) && (K | P | N)) {
ll ans = go(K, N, P);
if (~ans)
printf("%I64d\n", ans);
else
puts("No Solution");
}
return 0;
}