离散对数二连 poj 2417 Discrete Logging & HDU 2815 Mod Tree
Posted TOTOTOTOTZZZZZ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了离散对数二连 poj 2417 Discrete Logging & HDU 2815 Mod Tree相关的知识,希望对你有一定的参考价值。
题目就不贴了。都是一样的套路求解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; }
以上是关于离散对数二连 poj 2417 Discrete Logging & HDU 2815 Mod Tree的主要内容,如果未能解决你的问题,请参考以下文章
BSGS算法+逆元 POJ 2417 Discrete Logging
Discrete Logging POJ - 2417(BSGS)
POJ-2417-Discrete Logging(BSGS)