1. 程式人生 > >POJ 3243 Clever Y (求X^Y mod Z = K)

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

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 ;
}