1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <queue> #include <set> #include <vector> using namespace std;
const int INF = ~0u>>1; typedef pair <int,int> P; typedef long long llg; #define MID(x,y) ((x+y)>>1) #define iabs(x) ((x)>0?(x):-(x)) #define REP(i,a,b) for(int i=(a);i<(b);i++) #define FOR(i,a,b) for(int i=(a);i<=(b);i++) #define pb push_back #define mp make_pair #define print() cout<<"--------"<<endl const int N = 100003; struct Baby_step_Giant_step{ struct edge{int key,times;edge*next;}g[N],*ls[N]; int e;
void add(int x,int times){ int hash = x % N; for (edge*t=ls[hash];t;t=t->next) if(t->key == x) return ; g[++e].key = x; g[e].times = times; g[e].next = ls[hash]; ls[hash] = &g[e]; }
int In(int x){ int hash = x % N; for (edge*t=ls[hash];t;t=t->next) if(t->key == x) return t->times; return -1; }
int Power_mod(int a,int b,int mod){ llg t = a, res = 1; while (b){ if (b&1) res = res * t % mod; t = t * t % mod; b >>= 1; } return (int)(res); }
llg exgcd(int a,int b,llg &x,llg &y){ if (b == 0){ x = 1; y = 0; return a; } llg g = exgcd(b,a%b,x,y); llg tx = x,ty = y; x = ty; y = tx - a/b*ty; return g; }
int solve(int a,int c,int p){ if (c >= p) return -1; int i,j; int x = 1; int t = 1; int s = (int)ceil(sqrt((double)p)); int res,cnt = 0; llg tx,ty,g; for (int i = 0; i <= 50; i++) if (Power_mod(a,i,p) == c) return i;
while ((g=exgcd(a,p,tx,ty)) != 1){ if (c%g) return -1; c /= g; p /= g; x = (llg)(a)/g*x%p; cnt ++; }
e = 0; memset(ls,0,sizeof(ls)); for (i = 0; i < s; i++) add(Power_mod(a,i,p),i);
for (int step = Power_mod(a,s,p),i = cnt; i < p; i += s,x = (llg)(x) * step % p){ g = exgcd(x,p,tx,ty); tx = tx * c % p; if (tx < 0) tx += p; res = In((int)tx); if (res == -1) continue; return res + i; } return -1; } }Number_Theory;
int main(){ int a,p,c; while(~scanf("%d%d%d", &a, &p, &c)){ int ans = Number_Theory.solve(a,c,p); if (ans == -1) puts("Orz,I can’t find D!"); else printf("%dn", ans); } return 0; }
|