1. 程式人生 > >離散對數二連 poj 2417 Discrete Logging & HDU 2815 Mod Tree

離散對數二連 poj 2417 Discrete Logging & HDU 2815 Mod Tree

tdi close efi 信息 euc xtend spl insert key

題目就不貼了。都是一樣的套路求解a^x % c = b的最小x

註意HDU的題目很坑,有b比c大和題目中輸出信息為全角引號的坑

下面貼的是HDU的版本,poj的改一下a,b,c順序和輸出就好

技術分享
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL;
#define MOD 99991
#define N 100005
struct Hash{
    bool f;
    LL Key;
    LL Value;
};
LL a,b,c;
Hash hashs[N];
void Init(){ for (int i=0;i<N;i++){ hashs[i].f = 0; hashs[i].Key = -1; hashs[i].Value = -1; } } void Insert(LL Key,LL Value){ LL t = Value % MOD; while (hashs[t].f && hashs[t].Value != Value){ t ++; t %= MOD; } if (!hashs[t].f){ hashs[t].f
= 1; hashs[t].Key = Key; hashs[t].Value = Value; } } LL Find(LL Value){ LL t = Value % MOD; while (hashs[t].f && hashs[t].Value != Value){ t ++; t %= MOD; } if (!hashs[t].f) return -1; return hashs[t].Key; } LL gcd(LL a, LL b){ if (b == 0) return a;
return gcd(b,a % b); } void Extended_Euclid(LL a,LL b,LL &x,LL &y){ if (b == 0){ x = 1; y = 0; return; } Extended_Euclid(b,a%b,x,y); LL tmp = x; x = y; y = tmp - (a / b) * y; } LL Baby_Step(LL a,LL b,LL c){ LL ret = 1; for (int i=0;i<=50;i++){ if (ret == b) return i; // cout << ret << endl; ret = ret * a % c; } // cout << "HERE"; LL ans = 1,tmp,cnt = 0; while ((tmp = gcd(a,c)) != 1){ if (b % tmp) return -1; b /= tmp; c /= tmp; ans = ans * (a/tmp) % c; cnt ++; } LL M = ceil(sqrt(1.0*c)); LL t = 1; for (int i=0;i<=M-1;i++){ Insert(i,t); t = t * a % c; } for (int i=0;i<=M-1;i++){ LL x,y; Extended_Euclid(ans,c,x,y); LL Value = x * b % c; Value = (Value + c) % c; LL Key = Find(Value); if (Key != -1) return i * M + Key + cnt; ans = ans * t % c; } return -1; } int main() { // freopen("test.in","r",stdin); // 該程序可求解a^x == b (mod c),註意輸入時數據a,b,c的順序 while (cin >> a >> c >> b){ Init(); if (b >= c){ cout << "Orz,I can’t find D!" << endl; continue; } if (a == 0 && b == 0 && c == 0) break; a %= c; b %= c; // in case a > c or b > c LL ans = Baby_Step(a,b,c); if (ans == -1){ cout << "Orz,I can’t find D!" << endl; } else cout << ans << endl; } return 0; }
View Code

離散對數二連 poj 2417 Discrete Logging & HDU 2815 Mod Tree