Baby Step Giant Step 模板题
POJ 2417 基础 Baby Step Giant Step http://poj.org/problem?id=2417
HDU 2815 扩展 Baby Step Giant Step http://acm.hdu.edu.cn/showproblem.php?pid=2815
POJ 3243 扩展 Baby Step Giant Step http://poj.org/problem?id=3243
扩展 Baby Step Giant Step 详细请看 http://hi.baidu.com/aekdycoin/item/236937318413c680c2cf29d4 - By AekdyCoin
POJ 2417 http://poj.org/problem?id=2417
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<map>
using namespace std;
typedef long long ll;
void exgcd(int a,int b,int &x,int &y){
if(b){exgcd(b,a%b,y,x);y-=(a/b)*x;}
else{x=1;y=0;}
}
int gcd(int a,int b){return b?gcd(b,a%b):a;}
#define mod 131071
int Hash1[mod];
int Hash2[mod];
int getHash(int n){
int tem=n%mod;
while(Hash1[tem]!=-1){
if(Hash1[tem]!=n){
tem++;
if(tem>=mod)
tem-=mod;
}
else break;
}
return tem;
}
inline int BSGS(int A,int B,int C){ // A^x=B % C
ll tem=1%C;
for(int i=0;i<=100;i++)
if(tem==B) return i;
else tem=tem*A%C;
ll D=1%C;
int d=0;
while((tem=gcd(A,C))!=1){
if(B%tem!=0) return -1;
d++;
C/=tem;
B/=tem;
D=(D*A/tem)%C;
}
memset(Hash1,-1,sizeof(Hash1));
memset(Hash2,-1,sizeof(Hash2));
int m=(int)ceil(sqrt((double)C));
tem=1%C;
ll K;
for(int i=0;i<=m;i++){
if(i==m) K=tem;
int h=getHash((int)tem);
if(Hash1[h]==-1) Hash1[h]=(int)tem,Hash2[h]=i;
tem=(tem*A)%C;
}
for(int i=0;i<=m;i++){
int u,v;
exgcd((int)D,C,u,v);
u=(((ll)u*B)%C+C)%C;
int h=getHash(u);
if(u>=0&&Hash1[h]!=-1)
return i*m+Hash2[h]+d;
D=D*K%C;
}
return -1;
}
int main(){
int A,B,C;
while(scanf("%d%d%d",&C,&A,&B)!=EOF){// A^x=B % C
int ans;
if((ans=BSGS(A,B,C))!=-1) printf("%d\n",ans);
else printf("no solution\n");
}
}
HDU 2815 http://acm.hdu.edu.cn/showproblem.php?pid=2815
Hash版:
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<map>
using namespace std;
typedef long long ll;
void exgcd(int a,int b,int &x,int &y){
if(b){exgcd(b,a%b,y,x);y-=(a/b)*x;}
else{x=1;y=0;}
}
int gcd(int a,int b){return b?gcd(b,a%b):a;}
#define mod 131071
int Hash1[mod];
int Hash2[mod];
int getHash(int n){
int tem=n%mod;
while(Hash1[tem]!=-1){
if(Hash1[tem]!=n){
tem++;
if(tem>=mod)
tem-=mod;
}
else break;
}
return tem;
}
inline int BSGS(int A,int B,int C){ // A^x=B % C
if(B>=C) return -1;
ll tem=1%C;
for(int i=0;i<=100;i++)
if(tem==B) return i;
else tem=tem*A%C;
ll D=1%C;
int d=0;
while((tem=gcd(A,C))!=1){
if(B%tem!=0) return -1;
d++;
C/=tem;
B/=tem;
D=(D*A/tem)%C;
}
memset(Hash1,-1,sizeof(Hash1));
memset(Hash2,-1,sizeof(Hash2));
int m=(int)ceil(sqrt((double)C));
tem=1%C;
ll K;
for(int i=0;i<=m;i++){
if(i==m) K=tem;
int h=getHash((int)tem);
if(Hash1[h]==-1) Hash1[h]=(int)tem,Hash2[h]=i;
tem=(tem*A)%C;
}
for(int i=0;i<=m;i++){
int u,v;
exgcd((int)D,C,u,v);
u=(((ll)u*B)%C+C)%C;
int h=getHash(u);
if(u>=0&&Hash1[h]!=-1)
return i*m+Hash2[h]+d;
D=D*K%C;
}
return -1;
}
int main(){
int A,B,C;
while(scanf("%d%d%d",&A,&C,&B)!=EOF){// A^x=B % C
int ans;
if((ans=BSGS(A,B,C))!=-1) printf("%d\n",ans);
else printf("Orz,I can’t find D!\n");
}
}
map版:
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<map>
using namespace std;
typedef long long ll;
void exgcd(int a,int b,int &x,int &y){
if(b){exgcd(b,a%b,y,x);y-=(a/b)*x;}
else{x=1;y=0;}
}
int gcd(int a,int b){return b?gcd(b,a%b):a;}
map<int,int> Hash;
inline int BSGS(int A,int B,int C){ // A^x=B % C
if(B>=C)return -1;
ll tem=1%C;
for(int i=0;i<=100;i++) //处理出小的
if(tem==B) return i;
else tem=tem*A%C;
ll D=1%C;
int d=0;
while((tem=gcd(A,C))!=1){ //降次
if(B%tem!=0) return -1;
d++;
C/=tem;
B/=tem;
D=(D*A/tem)%C;
}
Hash.clear();
int m=(int)ceil(sqrt((double)C));
tem=1%C;
ll K;
for(int i=0;i<=m;i++){
if(i==m) K=tem;
if(Hash.find((int)tem)==Hash.end()) Hash[(int)tem]=i;
tem=(tem*A)%C;
}
for(int i=0;i<=m;i++){
int u,v;
exgcd((int)D,C,u,v);
u=(((ll)u*B)%C+C)%C;
if(u>=0&&Hash.find(u)!=Hash.end())
return i*m+Hash[u]+d;
D=D*K%C;
}
return -1;
}
int main(){
int A,B,C;
while(scanf("%d%d%d",&A,&C,&B)!=EOF){// A^x=B % C
int ans;
if((ans=BSGS(A,B,C))!=-1) printf("%d\n",ans);
else printf("Orz,I can’t find D!\n");
}
}