首页 > 代码库 > BZOJ3239 Discrete Logging
BZOJ3239 Discrete Logging
一道裸的BSGS题目(叫baby step, giant step)
从爱酱的blog里学来的,是一个很神的根号算法。
如果我们有hash的工具的话,就是O(sqrt(p))的,这里又用了一个map所以是O(sqrt(p) * log(sqrt(p)))
1 /************************************************************** 2 Problem: 3239 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:280 ms 7 Memory:2932 kb 8 ****************************************************************/ 9 10 #include <cstdio>11 #include <cmath>12 #include <map>13 14 using namespace std;15 typedef long long ll;16 17 ll p, y, z, B;18 map <ll, int> mp;19 20 ll pow(ll a, ll x) {21 a %= p;22 ll res = 1, base = a;23 while (x) {24 if (x & 1) (res *= base) %= p;25 (base *= base) %= p;26 x >>= 1;27 }28 return res;29 }30 31 int main() {32 ll i, now, base, tmp;33 while (scanf("%lld%lld%lld", &p, &y, &z) != EOF) {34 mp.clear();35 y %= p;36 if (!y) {37 if (!z) puts("1");38 else puts("no solution");39 goto end_of_work;40 }41 B = (int) ceil(sqrt(p)), now = 1;42 mp[1] = B + 1;43 for (i = 1; i < B; ++i) {44 (now *= y) %= p;45 if (!mp[now]) mp[now] = i;46 }47 now = 1, base = pow(y, p - B - 1);48 for (i = 0; i < B; ++i) {49 tmp = mp[z * now % p];50 if (tmp) {51 if (tmp == B + 1) tmp = 0;52 printf("%lld\n", i * B + tmp);53 goto end_of_work;54 }55 (now *= base) %= p;56 }57 puts("no solution");58 end_of_work:;59 }60 return 0;61 }
(p.s. bz上开了O2,所以还不是很慢恩!)
BZOJ3239 Discrete Logging
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。