BZOJ2242计算器

http://www.lydsy.com/JudgeOnline/problem.php?id=2242

此题就是入门的模板题

分别用到了快速幂取模

利用扩展欧几里得算法计算线性同余方程

利用 Baby Step Giant Step 算法解高次同余方程

典型的模板题

我把第三个算法翻译成为宝宝一小步,巨人一大步算法

我也不知道为什么会有这种算法名字

要是我发明了什么算法一定以自己的名字加附上冠

BSGS算法模板

ll BSGS(ll a,ll b,ll p){
    map<ll,ll> Hash;
    Hash.clear();
    b%=p;
    ll t=(ll)sqrt(p)+1;
    for(ll j=0;j<t;++j){
        ll val=b*quickmod(a,j,p)%p;
        Hash[val]=j;
    }
    a=quickmod(a,t,p);
    if(a==0)
        return b==0?1:-1;
    for(ll i=0;i<=t;++i){
        int val=quickmod(a,i,p);
        ll j=Hash.find(val)==Hash.end()?-1:Hash[val];
        if(j>=0&&i*t-j>=0)
            return i*t-j;
    }
    return -1;
}

以及AC代码:

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

ll quickmod(ll a,ll b,ll m){ll ans=1;while(b)
{if(b&1)ans=(ans*a)%m;b>>=1;a=a*a%m;}return ans;}

ll exgcd(ll a,ll b,ll &x,ll &y){if (b==0){x=1,y=0;
return a;}ll q=exgcd(b,a%b,y,x);y-=a/b*x;return q;}

ll BSGS(ll a,ll b,ll p){
    map<ll,ll> Hash;
    Hash.clear();
    b%=p;
    ll t=(ll)sqrt(p)+1;
    for(ll j=0;j<t;++j){
        ll val=b*quickmod(a,j,p)%p;
        Hash[val]=j;
    }
    a=quickmod(a,t,p);
    if(a==0)
        return b==0?1:-1;
    for(ll i=0;i<=t;++i){
        int val=quickmod(a,i,p);
        ll j=Hash.find(val)==Hash.end()?-1:Hash[val];
        if(j>=0&&i*t-j>=0)
            return i*t-j;
    }
    return -1;
}

int main(){
    ll T,K,y,z,p,a,x;
    cin>>T>>K;
    if(K==1){
        while(T--){
            cin>>y>>z>>p;
            cout<<quickmod(y,z,p)<<endl;
        }
    }
    if(K==2){
        while(T--){
            cin>>y>>z>>p;
            ll G=exgcd(y,p,x,a);
            if(z%G!=0){
                cout<<"Orz, I cannot find x!"<<endl;
                continue;
            }
            x=z/G*x;
            p/=G;
            if(x>=0)
                x%=p;
            else{
                while(x<0){
                    x+=p;    
                }
            }
            cout<<x<<endl;
        }
    }
    if(K==3){
        while(T--){
            cin>>y>>z>>p;
            ll ans=BSGS(y,z,p);
            if(ans==-1){
            	cout<<"Orz, I cannot find x!"<<endl;
			}
			else
				cout<<ans<<endl;
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值