[bzoj2242][SDOI2011][计算器] (Baby-Step-Giant-Step+快速幂+exgcd)

Description

你被要求设计一个计算器完成以下三项任务:
1、给定y,z,p,计算Y^Z Mod P 的值;
2、给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数;
3、给定y,z,p,计算满足Y^x ≡ Z ( mod P)的最小非负整数。

Input

 输入包含多组数据。

第一行包含两个正整数T,K分别表示数据组数和询问类型(对于一个测试点内的所有数据,询问类型相同)。
以下行每行包含三个正整数y,z,p,描述一个询问。

Output

对于每个询问,输出一行答案。对于询问类型2和3,如果不存在满足条件的,则输出“Orz, I cannot find x!”,注意逗号与“I”之间有一个空格。

Sample Input

【样例输入1】
3 1
2 1 3
2 2 3
2 3 3
【样例输入2】
3 2
2 1 3
2 2 3
2 3 3
【数据规模和约定】
对于100%的数据,1<=y,z,p<=10^9,为质数,1<=T<=10。

Sample Output

【样例输出1】
2
1
2
【样例输出2】
2
1
0

HINT

Source

第一轮day1

#include <map>
#include <math.h>
#include <stdio.h>
#define L long long
#define inf ~0U>>1
#define dmin(a,b) ((a)<(b)?(a):(b))

template<class Type>inline void Rin(Type &x){
  x=0;Type c=getchar(),f=1;
  for(;c<48||c>57;c=getchar())
    if(c==45)f=-1;
  for(;c>47&&c<58;c=getchar())
    x=(x<<1)+(x<<3)+c-48;
  x*=f;
}

std::map<int,int>mp;

int T,Kd;

struct Pep{
  L fir,sec;

  Pep(L _=0,L __=0) : fir(_),sec(__) {}
};

L gcd(L a,L b){
  return b?gcd(b,a%b):a;
}

Pep exgcd(L a,L b){
  if(!b)return Pep(1,0);
  Pep temp=exgcd(b,a%b);
  return Pep(temp.sec,temp.fir-a/b*temp.sec);
}

L frog1(L y,int p,L mo){
  L res=1LL;
  while(p){
    if(p&1)res=(res*y)%mo;
    y=(y*y)%mo;
    p>>=1;
  }
  return res;
}

void frog2(int a,int b,L p){
  p=-p;
  int t=gcd(a,p);
  if(b%t){puts("Orz, I cannot find x!");return;}
  a/=t; b/=t; p/=t;
  Pep temp=exgcd(a,p);
  temp.fir=(L)(temp.fir*b)%p;
  while(temp.fir<0)temp.fir+=p;
  printf("%d\n",temp.fir);
}

void frog3(int A,int B,L p){
  A%=p;
  if((!A) && (!B)){puts("1");return;}
  if((!A)){puts("Orz, I cannot find x!");return;}
  mp.clear();
  L m=ceil(sqrt(p)),temp=1LL;
  mp[1]=m+1;
  for(L i=1;i<m;i++){
    (temp*=A)%=p;
    if(!mp[temp])mp[temp]=i;
  }
  L D=frog1(A,p-m-1,p),ine=1LL;
  for(L k=0;k<m;k++){
    int i=mp[B*ine%p];
    if(i){
      if(i==m+1)i=0;
      printf("%lld\n",k*m+i);
      return;
    }
    ine=ine*D%p;
  }
  puts("Orz, I cannot find x!");
}

int main(){
  Rin(T); Rin(Kd);
  while(T--){
    int y,z,p;
    Rin(y),Rin(z),Rin(p);
    if(Kd==1)printf("%lld\n",frog1(y,z,p));
    else if(Kd==2)frog2(y,z,p);
    else frog3(y,z,p);
  }
  return 0;
}

 

posted @ 2017-01-22 23:37  keshuqi  阅读(138)  评论(0编辑  收藏  举报