题目连接:
http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=2399
题目类型:
数论 - 高次同余方程
数据结构:
struct LMIC_HASHTABLE
{
int i;
int key[N],
value[N];
void init()
{
for( i = 0; i < N; i ++ )
{
key[i] = -1;
value[i] = -1;
}
}
void insert( int k, int v )
{
int kk = k % N;
while( key[kk] != -1 && key[kk] != k )
{
kk = ( kk + 1 ) % N;
}
key[kk] = k;
value[kk] = v;
}
int find( int k )
{
int kk = k % N;
while( key[kk] != -1 && key[kk] != k )
{
kk = ( kk + 1 ) % N;
}
return value[kk];
}
} ;
思路分析:
题目要求 求出 B ^ L = N ( mod p ) 的方程解 L
利用循环验证的方法
证明:
略
源代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define N 100000
struct hashtable
{
int key[N];
int value[N];
void init()
{
for(int i=0;i<N;i++)key[i]=-1,value[i]=-1;
}
void insert(int k,int v)
{
int kk=k%N;
while(key[kk]!=-1&&key[kk]!=k) kk=(kk+1)%N;
key[kk]=k,value[kk]=v;
}
int find(int k)
{
int kk=k%N;
while(key[kk]!=-1&&key[kk]!=k) kk=(kk+1)%N;
return value[kk];
}
} h;
int baby_giant(int x,int k,int z)
{
x%=z,k%=z;
int m=(int)ceil(sqrt(1.0*z)),pre=1;
h.init();h.insert(k,0);
for(int i=1; i<=m; i++)
{
pre=(1ll*pre*x)%z;
h.insert((1ll*pre*k)%z,i);
}
for(int i=0,xm=pre,y=1;i*m<=z;i++)
{
int j=h.find(y);
if(j>=0&&i*m-j>=0) return i*m-j;
y=(1ll*y*xm)%z;
}
return -1;
}
int main()
{
int b,n,p;
while( scanf( "%d%d%d", &p, &b, &n ) != EOF )
{
int ans = baby_giant(b,n,p);
if( ans >= 0 )
{
cout<<ans<<endl;
}
else
{
puts( "no solution" );
}
}
return 0;
}