1636:【例 6】计算器

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll T,K;ll y,z,p;
void solve1()
{
    ll ans=1;
    while(z)
    {
        if(z&1) ans=ans*y%p;
        y=y*y%p;
        z>>=1;
    }
    printf("%lld\n",ans);
}
void exgcd(ll a,ll b,ll &d,ll &x,ll &y0)
{
    if(!b)
    {
        d=a;
        x=1;
        y0=0;
    }
    else
    {
        exgcd(b,a%b,d,x,y0);
        ll t=x;
        x=y0;
        y0=t-a/b*y0;
    }
}
ll gcdd(ll x,ll y0)
{
    if(y0==0)
    return x;
    return gcdd(y0,x%y0);
}
void solve2()
{
    ll d,x,y0;
    exgcd(y,p,d,x,y0);
    if(z%d!=0) 
    {
        printf("Orz, I cannot find x!\n");
        return ;
    }
    printf("%lld\n",((z/d*x)%(p/d)+p/d)%(p/d));
}
map<ll,ll>Map;
void solve3()
{
    ll d=1,x,y0,gcd,dd;
    Map.clear();
    y%=p;
    //z%=p;
    dd=gcdd(y,p);
    if(dd!=1) {    printf("Orz, I cannot find x!\n");return ;}
    ll m=ceil(sqrt(p)),tmp=1;
    Map[1]=m+1;
    for(ll i=1;i<m;i++)
    {
        tmp=tmp*y%p;
        if(!Map[tmp]) Map[tmp]=i;
    }
    tmp=tmp*y%p;
    for(ll j=0;j<m;j++)
    {
        exgcd(d,p,gcd,x,y0);
        x=((x*z/gcd)%(p/gcd)+p/gcd)%(p/gcd);
        int t=Map[x];
        if(t)
        {
            if(t==m+1) t=0;
            printf("%lld\n",j*m+t);
            return;
        }
        d=d*tmp%p;
    }
    printf("Orz, I cannot find x!\n");
}
int main()
{
    scanf("%lld%lld",&T,&K);
    while(T--)
    {
        scanf("%lld%lld%lld",&y,&z,&p);
        if(K==1) solve1();
        else if(K==2) solve2();
        else solve3();
    }
    return 0;
}

这道题只要用朴素算法的bsgs就行了,数据中的情况都是基本情况没有变形但是要注意加一个判断语句

posted @ 2019-08-24 16:38  Gold_stein  阅读(268)  评论(0编辑  收藏  举报