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 }
View Code

(p.s. bz上开了O2,所以还不是很慢恩!)

转载于:https://www.cnblogs.com/rausen/p/4263251.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值