一本通1636【例 6】计算器

1636:【例 6】计算器

【输入样例】

3 1
2 1 3
2 2 3
2 3 3

【输出样例】

2
1
2

【提示】

样例输入 2

3 2
2 1 3
2 2 3
2 3 3

样例输出 2

2
1
0

sol:以前看来很水的题目现在已经有点做不动了qaq

三个板子凑起来,随便提一句BSGS

其实只是一种优化的暴力

y^x = z (%Mod)
x = k*B+i (B=sqrt(Mod))
y^(k*B+i) = z (%Mod)
y^(k*B)*(y^i) = z (%Mod)
y^i = z/y^(k*B) (%Mod)
y^i = z*(Inv^k) (Inv = 1/(y^B) )

我还不会exbsgs,只会做Mod是质数的情况

Ps:map自带大常数,所以跑的很慢,这是没办法的事

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read()
{
    ll s=0;
    bool f=0;
    char ch=' ';
    while(!isdigit(ch))
    {
        f|=(ch=='-'); ch=getchar();
    }
    while(isdigit(ch))
    {
        s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
    }
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0)
    {
        putchar('-'); x=-x;
    }
    if(x<10)
    {
        putchar(x+'0'); return;
    }
    write(x/10);
    putchar((x%10)+'0');
    return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('
')
int T;
namespace Ask1
{
    inline ll Ksm(ll x,ll y,ll Mod)
    {
        ll ans=1;
        while(y)
        {
            if(y&1) ans=ans*x%Mod;
            x=x*x%Mod;
            y>>=1;
        }
        return ans;
    }
    inline void Solve()
    {
        while(T--)
        {
            ll y=read(),z=read(),Mod=read();
            Wl(Ksm(y,z,Mod));
        }
    }
}
namespace Ask2
{
    /*
        x*y = z (%Mod)
        x*y+k*Mod = z (类ax+by=c的形式)
    */
    inline ll gcd(ll x,ll y)
    {
        return (!y)?(x):(gcd(y,x%y));
    }
    inline void Exgcd(ll a,ll b,ll &X,ll &Y)
    {
        if(b==0)
        {
            X=1;
            Y=0;
            return;
        }
        Exgcd(b,a%b,X,Y);
        ll XX=X,YY=Y;
        X=YY;
        Y=XX-a/b*YY;
        return;
    }
    inline void Solve()
    {
        ll a,b,c,r,X,Y;
        while(T--)
        {
            ll y=read(),z=read(),Mod=read();
            a=y;
            b=Mod;
            c=z;
            r=gcd(a,b);
            if(c%r)
            {
                puts("Orz, I cannot find x!");
                continue;
            }
            Exgcd(a,b,X=0,Y=0);
            X=X*c/r;
            ll tmp=b/r;
            X=(X%tmp+tmp)%tmp;
            Wl(X);
        }
    }
}
/*
    y^x = z (%Mod)
    x = k*B+i (B=sqrt(Mod))
    y^(k*B+i) = z (%Mod)
    y^(k*B)*(y^i) = z (%Mod)
    y^i = z/y^(k*B) (%Mod)
    y^i = z*(Inv^k) (Inv = 1/(y^B) )
*/
namespace Ask3
{
    map<ll,ll>Map;
    inline ll Ksm(ll x,ll y,ll Mod)
    {
        ll ans=1;
        while(y)
        {
            if(y&1) ans=ans*x%Mod;
            x=x*x%Mod;
            y>>=1;
        }
        return ans;
    }
    inline void Solve()
    {
        ll i,j;
        while(T--)
        {
            Map.clear();
            ll y=read(),z=read(),Mod=read();
            if(y%Mod==0)
            {
                puts("Orz, I cannot find x!");
                continue;
            }
            ll B=sqrt(Mod*1.0),j=1;
            Map[1]=0;
            for(i=1;i<=B;i++)
            {
                j=j*y%Mod;
                if(!Map[j]) Map[j]=i;
            }
            ll Inv=Ksm(j,Mod-2,Mod);
            j=1ll;
            ll ans=-1;
            for(i=B;(i<=Mod)&&(ans==-1);i+=B)
            {
                j=j*Inv%Mod;
                int oo=Map[z*j%Mod];
                if(oo!=0)
                {
                    ans=i+oo;
                    break;
                }
            }
            (ans==-1)?puts("Orz, I cannot find x!"):(Wl(ans));
        }
    }
}
int main()
{
    int opt;
    R(T); R(opt);
    switch (opt)
    {
        case 1:
            Ask1::Solve();
            break;
        case 2:
            Ask2::Solve();
            break;
        case 3:
            Ask3::Solve();
            break;
        default:
            break;
    }
    return 0;
}
/*
input
1 3
146324954 14948940 73162477
output
Orz, I cannot find x!
*/
View Code
原文地址:https://www.cnblogs.com/gaojunonly1/p/10473670.html