大步小步算法 模板bzoj 计算器

你被要求设计一个计算器完成以下三项任务:
1、给定y,z,p,计算Y^Z Mod P 的值;
2、给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数;
3、给定y,z,p,计算满足Y^x ≡ Z ( mod P)的最小非负整数。
 

 code:

//
#include<bits/stdc++.h>
using namespace std;
#define ll long long 
ll T,p;
ll ksm(ll a,ll b,ll c)
{
    ll ans=1;
    while(b)
    {
        if(b&1) ans=(ans*a)%c;
        b>>=1;
        a=(a*a)%c;
    }
    return ans;
}
map <ll,ll> mapp;
ll BSGS (ll a,ll b,ll c)
{
    if(!a) return b? -1:1;
    if(b==1) return 0;
    mapp.clear();
    ll ax=1;
    ll m=ceil(sqrt(c));
    for(int i=0;i<m;i++)
    {
        mapp[ax]=i;
        ax=(ax*a)%c;
    }
    ll am=ksm(a,m,c);
    for(int i=1;i<=m;i++)
    {
        if(mapp.count((am*ksm(b,c-2,c))%c)) return i*m-mapp[(am*ksm(b,c-2,c))%c];
        am=(am*ksm(a,m,c))%c;
    }
    return -1;
}
int main()
{
    cin>>T;
    ll y , z , d;
    scanf("%lld",&p);
    while(T--)
    {
    
        if(p==1)
        {
            scanf("%lld%lld%lld",&y,&z,&d);
            printf("%lld\n",ksm(y,z,d));
        }else
        if(p==2)
        {
            scanf("%lld%lld%lld",&y,&z,&d);
            if(y%d==0) puts("Orz, I cannot find x!");
            else
            printf("%lld\n",(ksm(y,d-2,d)*z)%d);
        }else
        if(p==3)
        {
            
            scanf("%lld%lld%lld",&y,&z,&d);
            ll ans=BSGS(y%d,z%d,d);
            if(~ans)
            printf("%lld\n",ans);
            else
            puts("Orz, I cannot find x!");
        }
    }
    
    
    
 } 

猜你喜欢

转载自www.cnblogs.com/OIEREDSION/p/11330034.html
今日推荐