luogu2485 [SDOI2011]计算器

Posted poorpool

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu2485 [SDOI2011]计算器相关的知识,希望对你有一定的参考价值。

BSGS 算法,即 Baby Step,Giant Step 算法、拔山盖世算法。
计算 \(a^x \equiv b \pmod p\)

\(p\)为质数时

由于费马小定理 \(x^{p-1} \equiv 1 \pmod p\)\(p\) 为质数,则要是暴力的话只需要枚举到 \(p-1\) 即可。
假设 \(x=it-j\),其中 \(t= \lceil \sqrt p \rceil,j \in [0,t]\),方程变为 \(a^{it-j} \equiv b \pmod p\),即 \(a^{it} \equiv ba^j \pmod p\)。我们惊喜地发现,左右最多也就 \(t\) 个左右种可能的取值(这就是 \(t\) 为什么取那个值的原因),那我们枚举 \(j\),把 \(ba^j\) 所对应的 \(j\) 都存起来,然后枚举 \(i\) 找有无对应即可。
\(ba^j\) 冲突怎么办?答:存 \(j\) 大的。因为要想 \(x\) 尽量小,就要让 \(j\) 尽量大。
第一个找到的 \(i\) 和它对应的 \(j\) 就是答案。为什么?答:因为 \(i\) 变化 \(1\)\(x\) 变化的幅度是 \(t\)

#include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
using namespace std;
typedef long long ll;
int T, k;
ll y, z, p;
map<int,int> d;
ll work1(ll a, ll b, ll p){
    ll re=1;
    while(b){
        if(b&1) re = (re * a) % p;
        a = (a * a) % p;
        b >>= 1;
    }
    return re;
}
ll exgcd(ll a, ll b, ll &x, ll &y){
    if(!b){
        x = 1;
        y = 0;
        return a;
    }
    ll re=exgcd(b, a%b, x, y);
    ll qwq=x;
    x = y;
    y = qwq - a / b * y;
    return re;
}
void work2(){
    ll u, v;
    ll gcd=exgcd(y, p, u, v);
    if(z%gcd)   printf("Orz, I cannot find x!\n");
    else
        printf("%lld\n", ((u*z/gcd)%(p/gcd)+(p/gcd))%(p/gcd));
}
void work3(){
    d.clear();
    int m=sqrt(p);
    if(m*m!=p)  m++;
    for(int i=0; i<=m; i++)
        d[int((z*work1(y, i, p))%p)] = i;
    if(!work1(y, m, p)){
        if(z)   printf("Orz, I cannot find x!\n");
        else    printf("1\n");
        return ;
    }
    for(int i=0; i<=m; i++){
        int tmp=work1(y, i*m, p);
        if(d.find(tmp)!=d.end() && (ll)i*m-d[tmp]>=0){
            printf("%lld\n", (ll)i*m-d[tmp]);
            return ;
        }
    }
    printf("Orz, I cannot find x!\n");
}
int main(){
    cin>>T>>k;
    while(T--){
        scanf("%lld %lld %lld", &y, &z, &p);
        if(k==1)    printf("%lld\n", work1(y, z, p));
        if(k==2)    work2();
        if(k==3)    work3();
    }
    return 0;
}

测试数据:

2 3
39 26 13
6 11 5
1
0

以上是关于luogu2485 [SDOI2011]计算器的主要内容,如果未能解决你的问题,请参考以下文章

P2485 [SDOI2011]计算器

P2485 [SDOI2011]计算器

P2485 [SDOI2011]计算器(快速幂+扩欧+bsgs)

#50: Luogu 2485 模板

BZOJ_2242_[SDOI2011]计算器_快速幂+扩展GCD+BSGS

luogu2486 [SDOI2011]染色