BZOJ2242: [SDOI2011] Calculator - Problem Solving POJ3243: Clever Y

https://www.lydsy.com/JudgeOnline/problem.php?id=2242

https://www.luogu.org/problemnew/show/P2485

You are asked to design a calculator to accomplish the following three tasks:
1. Given y, z, p, calculate the value of Y^Z Mod P;
2. Given y, z, p, calculate the smallest non-negative integer that satisfies xy≡ Z (mod P);
3. Given y, z, p, calculate the smallest non-negative integer that satisfies Y^x ≡ Z (mod P).

A hodgepodge of questions:

1 operation fast power.

2. Divide y by the past multiplicative inverse to find x, and pay attention to determine whether there is a multiplicative inverse.

3 operation is POJ3243: Clever Y.

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cctype>
#include<cstdio>
#include<cmath>
#include<stack>
using namespace std;
typedef long long ll;
const int N=999979;
const int M=40005;
struct HASH{
    int w,to,nxt;
}h[M];
int cnt,head[N];
inline void add(int x,int y){
    int t=x%N;
    for(int i=head[t];i;i=h[i].nxt){
        int v=h[i].to;
        if(v==x){
            h[i].w =y; // Remember the big 
            return ;
        }
    }
    h[++cnt].to=x;h[cnt].w=y;h[cnt].nxt=head[t];head[t]=cnt;
}
inline int query(int x){
    int t=x%N;
    for(int i=head[t];i;i=h[i].nxt){
        int v=h[i].to;
        if(v==x)return h[i].w;
    }
    return -1;
}
int gcd(int a,int b){
    return (!b)?a:gcd(b,a%b);
}
int exgcd(int a,int b,int &x,int &y){
    if(!b){
        x=1,y=0;
        return a;
    }
    int ans=exgcd(b,a%b,y,x);
    y-=(ll)(a/b)*x;
    return ans;
}
int inv ( int a, int c) {
     int x, y;
    exgcd(a,c,x,y);
    return (x%c+c)%c;
}
//a^x=b(mod c);
int BSGS(int a,int b,int c){
    if(!a){
        if(!b)return 1;
        return -1;
    }
    int tot=0,g,d=1;
    while((g=gcd(a,c))!=1){
        if(b%g)return -1;
        ++tot;b/=g,c/=g;
        d=(ll)d*(a/g)%c;
    }
    b=(ll)b*inv(d,c)%c;
    cnt=0;memset(head,0,sizeof(head));
    int s=sqrt(c),p=1;
    for(int i=0;i<s;i++){
        if(p==b)return i+tot;
        add((ll)p*b%c,i);
        p=(ll)p*a%c;
    }
    int q=p;
    for(int i=s;i-s+1<c;i+=s){
        int t=query(q);
        if(t!=-1)return i-t+tot;
        q=(ll)q*p%c;
    }
    return -1;
}
int qpow(int k,int n,int p){
    int res=1;
    while(n){
        if(n&1)res=(ll)res*k%p;
        k=(ll)k*k%p;
        n>>=1;
    }
    return res;
}
int main(){
    int T,k;
    scanf("%d%d",&T,&k);
    while(T--){
        int y,z,p;
        scanf("%d%d%d",&y,&z,&p);
        if(k==1)printf("%d\n",qpow(y,z,p));
        if(k==2){
            if(y%p==0)puts("Orz, I cannot find x!");
            else printf("%lld\n",(ll)z*qpow(y,p-2,p)%p);
        }
        if(k==3){
            y%=p,z%=p;
            int ans=BSGS(y,z,p);
            if(ans==-1)puts("Orz, I cannot find x!");
            else printf("%d\n",ans);
        }
    }
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

+ Author of this article: luyouqi233. +

+Welcome to my blog: http://www.cnblogs.com/luyouqi233/  +

+++++++++++++++++++++++++++++++++++++++++++

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325274171&siteId=291194637