[CQOI 2018]破解D-H协议

Description

题库链接

给出 \(A,B,P,g\)\(g\)\(P\) 的原根,求出 \(A\equiv g^a\pmod{P}\)\(B\equiv g^b\pmod{P}\) 中的 \(a,b\) ,并输出 \(g^{ab}\)

\(2\leq A,B<P<2^{31},2\leq g<20,1\leq n\leq 20\)

Solution

\(BSGS\) 板子啊,由于 \(g\)\(P\) 原根,解是唯一的。

Code

#include <bits/stdc++.h>
using namespace std;

map<int, int>mp;
int g, p, n, a, b;

int quick_pow(int a, int b) {
    int ans = 1;
    while (b) {
        if (b&1) ans = 1ll*ans*a%p;
        b >>= 1, a = 1ll*a*a%p;
    }
    return ans;
}
int BSGS(int a, int b) {
    mp.clear();
    int lim = ceil(sqrt(p)), cnt = b%p;
    for (int i = 0; i <= lim; i++, cnt = 1ll*cnt*a%p)
        mp[cnt] = i;
    int t = cnt = quick_pow(a, lim);
    for (int i = 1; i <= lim; i++, cnt = 1ll*cnt*t%p)
        if (mp.count(cnt)) return lim*i-mp[cnt];
}
void work() {
    scanf("%d%d%d", &g, &p, &n);
    while (n--) {
        scanf("%d%d", &a, &b);
        a = BSGS(g, a); printf("%d\n", quick_pow(b, a)) ;
    }
}
int main() {work(); return 0; }

转载于:https://www.cnblogs.com/NaVi-Awson/p/8987728.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值