Poj 2417 Discrete Logging —— BSGS模板

This way

题意:

告诉你B,N,P,让你求最小的L使得
在这里插入图片描述

题解:

BSGS模板,大致意思是将L变成ax+b的形式,定下x之后,式子就变成了这样:
B b = = N B − a x ( m o d P ) B^b==NB^{-ax}(mod P) Bb==NBax(modP)
那么我们只需要先枚举b(0<=b<=x),将所有值都记下来,再枚举a,同时查询即可。
这道题如果将x设为 P \sqrt{P} P 的话会T,或许是我写的教丑,在经过一系列的尝试之后,确定x在2e3~3e3这个范围最优。
在这里插入图片描述

#include<stdio.h>
#include<iostream>
#include<map>
#include<math.h>
using namespace std;
#define ll long long
ll mod;
const ll inf=1e10; 
ll qpow(ll a,ll b){ll ans=1;for(;b;b>>=1,a=a*a%mod)if(b&1)ans=ans*a%mod;return ans;}
map<ll,int>mp;
int main()
{
    ll b,n;
    while(scanf("%lld%lld%lld",&mod,&b,&n)!=EOF){
        mp.clear();
        int x=min(2500,(int)sqrt(mod)+1);
        ll v=1;
        ll ans=inf;
        for(int i=0;i<=x;i++,v=v*b%mod){
            if(mp.count(v))break;
            mp[v]=i;
            if(v==n)ans=min(ans,1ll*i);
        }
        v=n;
        ll ret=qpow(b,x);
        ret=qpow(ret,mod-2);
        ll top=mod/x+1;
        for(int i=0;i<=top;i++){
            if(mp.count(v))ans=min(ans,1ll*i*x+mp[v]);
            if(v==1&&i!=0)ans=min(ans,1ll*i*x);
            if(i*x>=ans)break;
            v=v*ret%mod;
        }
        if(ans==inf)printf("no solution\n");
        else printf("%lld\n",ans);
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值