您的位置:首页 > 其它

POJ 3243 Clever Y (求X^Y mod Z = K)

2015-09-21 20:42 357 查看
Clever Y

Time Limit: 5000MS Memory Limit: 65536K
Total Submissions: 7301 Accepted: 1807
Description

Little Y finds there is a very interesting formula in mathematics:

XY mod Z = K
Given X, Y, Z, we all know how to figure out
K fast. However, given X, Z, K, could you figure out
Y fast?

Input
Input data consists of no more than 20 test cases. For each test case, there would be only one line containing 3 integers
X, Z, K (0 ≤ X, Z, K ≤ 109).

Input file ends with 3 zeros separated by spaces.

Output
For each test case output one line. Write "No Solution" (without quotes) if you cannot find a feasible
Y (0 ≤ Y < Z). Otherwise output the minimum Y you find.
Sample Input
5 58 33
2 4 3
0 0 0

Sample Output
9No Solution

套模板
#include<stdio.h>
#include<string.h>
#include<math.h>
#include <iostream>
#include<stdlib.h>
#include <algorithm>
using namespace std;
#define CC(m ,what) memset(m , what , sizeof(m))
typedef __int64 LL ;
LL A, B ,C ;
const int NN = 99991 ;
bool hash[NN] ;
int idx[NN] , val[NN] ;

void insert(int id , LL vv)
{
LL v = vv % NN ;
while( hash[v] && val[v]!=vv)
{
v++ ;
if(v == NN) v-=NN ;
}
if( !hash[v] )
{
hash[v] = 1;
val[v] = vv ;
idx[v] = id ;
}
}
int find(LL vv)
{
LL v = vv % NN ;
while( hash[v] && val[v]!=vv)
{
v++ ;
if(v == NN) v-=NN ;
}
if( !hash[v] ) return -1;
return idx[v] ;
}
void ex_gcd(LL a , LL b , LL& x , LL& y)
{
if(b == 0)
{
x = 1 ;
y = 0 ;
return ;
}
ex_gcd(b , a%b , x, y) ;
LL t = x ;
x = y;
y = t - a/b*y ;
}
LL gcd(LL a,LL b)
{
while( a%b != 0)
{
LL c = a ;
a = b ;
b = c % b ;
}
return b ;
}
LL baby_step(LL A, LL B , LL C)
{
LL ans = 1 ;
for(LL i=0; i<=50; i++)
{
if(ans == B) return i ;
ans = ans * A % C ;
}
LL tmp , d = 0 ;
LL D = 1 % C ;
while( (tmp=gcd(A,C)) != 1 )
{
if(B % tmp) return -1 ;
d++ ;
B/=tmp ;
C/=tmp ;
D = D*A/tmp%C ;
}
CC( hash , 0) ;
CC( idx, -1) ;
CC(val , -1) ;
LL M = ceil( sqrt(C*1.0) ) ;
LL rr = 1 ;
for(int i=0; i<M; i++)
{
insert(i, rr) ;
rr = rr * A % C ;
}
LL x, y ;
for(int i=0; i<M; i++)
{
ex_gcd(D, C , x, y) ;
LL r = x * B % C;
r = (r % C + C) % C ;
int jj = find( r ) ;
if(jj != -1)
{
return LL(i)*M + LL(jj) + d ;
}
D = D * rr % C ;
}
return -1 ;
}
int main()
{
while(scanf("%I64d %I64d %I64d",&A,&C,&B) == 3)
{
if(A+B+C == 0 ) break ;
LL res = baby_step(A,B,C) ; //A%C==B;
if( res == -1 )
{
printf("No Solution\n");
continue ;
}
printf("%I64d\n",res);
}
return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM算法