LOJ 10214 计算器 题解

题面

k==1时,快速幂就好了;

k==2时,exgcd就好了,但要注意取模范围的控制;

k==3时,BSGS可以解决高次同余方程:

 

然后就可以开心的A掉了,但要注意特殊情况的特判

 

#include <bits/stdc++.h>
using namespace std;
long long KSM(long long a,long long b,long long p)
{
    long long res=1;
    while(b){
        if(b&1) res=res*a%p;
        a=a*a%p;
        b/=2;
    }
    return res%p;
}
void solve1(int t)
{
    while(t--){
        long long y,z,p;
        cin>>y>>z>>p;
        printf("%lld\n",KSM(y,z,p)%p);
    }
}
long long d;
void exgcd(long long a,long long b,long long &x,long long &y)
{
    if(b==0){
        x=1;
        y=0;
        d=a;
        return;
    }    
    exgcd(b,a%b,y,x);
    y-=(a/b)*x;    
}
void solve2(int t)
{
    while(t--){
        long long y,z,p;
        cin>>y>>z>>p;
        long long ha,la;
        exgcd(y,p,ha,la);
        if(z%d!=0){
            cout<<"Orz, I cannot find x!"<<endl;
        }
        else{
            cout<<(((z*ha/d)%p+p)%p+p)%p<<endl;
        }
    }
}
void BSGS(long long a,long long ans,long long p)
{
    map<long long ,long long> Myhash;
    ans%=p;
    int tmp=sqrt(p)+1;
    for(int i=0;i<tmp;i++){
        Myhash[(ans*KSM(a,i,p))%p]=i;
    }
    a=KSM(a,tmp,p)%p;
    if(a==0&&ans==0){
        cout<<"1"<<endl;
        return;
    }
    if(a==0&&ans!=0){
        cout<<"Orz, I cannot find x!"<<endl;
        return;
    }
    for(int i=0;i<=tmp;i++){
        if(Myhash.find(KSM(a,i,p))!=Myhash.end()&&(i*tmp-Myhash[KSM(a,i,p)]>=0)){
            cout<<i*tmp-Myhash[KSM(a,i,p)]<<endl;
            return;
        }        
    }
    cout<<"Orz, I cannot find x!"<<endl;
}
void solve3(int t)
{
    while(t--){
        long long y,z,p;
        cin>>y>>z>>p;
        BSGS(y,z,p);
    }
}
int main()
{
    int t,k;
    cin>>t>>k;
    if(k==1){
        solve1(t);
    }
    else if(k==2){
        solve2(t);
    }
    else solve3(t);    
}

 

posted @ 2019-09-20 11:36  神之右大臣  阅读(253)  评论(0编辑  收藏  举报