• BZOJ 2242 [SDOI2011]计算器 ——EXGCD/快速幂/BSGS


    三合一的题目。

    exgcd不解释,快速幂不解释。

    BSGS采用了一种不用写EXGCD的方法,写起来感觉好了很多。

    比较坑,没给BSGS的样例(LAJI)

    #include <map>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
     
    #define F(i,j,k) for (ll i=j;i<=k;++i)
    #define D(i,j,k) for (ll i=j;i>=k;--i)
    #define ll long long
     
    map <ll,ll> mp;
     
    ll t,k;
     
    ll qpow(ll a,ll b,ll p)
    {
        ll ret=1;
        while (b)
        {
            if (b&1) ret=(ll)ret*a%p;
            a=(ll)a*a%p;
            b>>=1;
        }
        return ret;
    }
     
    void solve1()
    {
        F(i,1,t)
        {
            ll a,b,p;
            scanf("%lld%lld%lld",&a,&b,&p);
            printf("%lld
    ",qpow(a,b,p));
        }
    }
     
    void exgcd(ll a,ll b,ll &d,ll &x,ll &y)
    {
        if (b==0) {x=1;y=0;d=a;return;}
        exgcd(b,a%b,d,y,x);
        y-=x*(a/b);
    }
     
    void solve2()
    {
        F(i,1,t)
        {
            ll a,b,p,x,y,z,d;
            scanf("%lld%lld%lld",&a,&b,&p);b%=p;
            exgcd(a,p,d,x,y);
            if (b%d)
            {
                printf("Orz, I cannot find x!
    ");
                continue;
            }
            x=x*(b/d);
            if (x>=0) x=x%p;
            else x=(0-x)/p*p+x;
            while (x<0) x+=p;
            printf("%lld
    ",x);
        }
    }
     
    void solve3()
    {
        F(i,1,t)
        {
            ll a,b,c;
            scanf("%lld%lld%lld",&a,&b,&c);
            mp.clear();
            if (a%c==0) {printf("Orz, I cannot find x!
    ");continue;}
            ll p=false;
            ll m=ceil(sqrt(c)),ans;
            for (ll i=0;i<=m;++i)
            {
                if (i==0)
                {
                    ans=b%c;mp[ans]=i;continue;
                }
                ans=((ll)ans*a)%c;
                mp[ans]=i;
            }
            ll tmp=qpow(a,m,c); ans=1;
            for (ll i=1;i<=m;++i)
            {
                ans=((ll)ans*tmp)%c;
                if (mp[ans])
                {
                    ll tmp=i*m-mp[ans];
                    printf("%lld
    ",(tmp%c+c)%c);
                    p=true;
                    break; 
                }
            }
            if (!p) printf("Orz, I cannot find x!
    ");
        }
    }
     
    int main()
    {
        scanf("%lld%lld",&t,&k);
        switch(k)
        {
            case 1: solve1(); break;
            case 2: solve2(); break;
            case 3: solve3(); break;
        }
    }
    

      

  • 相关阅读:
    【BestCoder #48】
    【一场模拟赛?】
    【普通の随笔】6.30
    【BestCoder #45】
    【BestCoder #44】
    【普通の惨败】GDOI2015卖萌记
    我的新博客
    【BZOJ 2964】Boss单挑战
    【NOI 2015】软件包管理器
    【NOI 2015】程序自动分析
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6581986.html
Copyright © 2020-2023  润新知