[SDOI2011]计算器(同余相关)

[SDOI2011]计算器(luogu)

Solution

k==1:快速幂

k==2:扩展欧几里得

k==3:BSGS

BSGS:

 

对于
$$y^x≡z\pmod{m}$$

 

设 $m=\sqrt{p}$ 上取整

 

则 $x$ 可表示为 $i*m-j$ ($0<=j<=m$)

 

于是
$$y^{i*m}≡z*y^j\pmod{m}$$

 

我们把 $0<=j<=m$ 的 $z*y^j\pmod{m}$ 存入哈希表

 

再依次查找 $1<=i<=m$ 的 $y^{i*m}\pmod{m}$ 再哈希表中是

 

否存在,若存在,则找到了最小的 $x$

 

Code

#include <cstdio>
#include <cstdlib>
#include <map>
#include <cmath>
#include <algorithm>
#define ll long long
using namespace std;
ll y,z,p;
int T,k;
ll qpow(ll x,ll y,ll p)
{
    ll ans=1;
    while(y)
    {
        if(y&1) ans=ans*x%p;
        x=x*x%p,y>>=1;
    }
    return ans;
}
ll exgcd(ll a,ll b,ll &x,ll &y)
{
    if(b==0)
    {
        x=1,y=0;
        return a;
    }
    ll r=exgcd(b,a%b,y,x);
    y-=(a/b)*x;
    return r;
}
int main()
{
    scanf("%d%d",&T,&k);
    while(T--)
    {
        scanf("%lld%lld%lld",&y,&z,&p);
        if(k==1) printf("%lld\n",qpow(y,z,p));
        else if(k==2)
        {
            ll n,m;
            ll c=exgcd(y,p,n,m);
            if(z%c) puts("Orz, I cannot find x!");
            else
            {
                n*=(z/c);
                ll mod=(p/c);
                printf("%lld\n",(n%mod+mod)%mod); 
            }    
        }
        else if(k==3)
        {
            if(y%p==0)
            {
                if(z) puts("Orz, I cannot find x!");
                else puts("0");
                continue;
            }
            map <ll,int> hs;
            ll sq=ceil(sqrt(p)),now=z%p,f=qpow(y,sq,p);
            for(int i=0;i<=sq;i++)
            {
                hs[now]=i+1;    
                now=now*y%p;
            }
            bool end=false;
            now=1;
            for(ll i=1;i<=sq;i++)
            {
                now=now*f%p;
                if(hs.count(now))
                {
                    printf("%lld\n",(i*sq-hs[now]+1+p)%p);
                    end=true;
                    break;
                }
            }
            if(!end) puts("Orz, I cannot find x!");
        }
    }
    return 0;
}

 

 

 

posted @ 2020-03-09 07:56  hsez_cyx  阅读(384)  评论(0)    收藏  举报