Timus 1110. Power

Timus 1110. Power 要求计算乘方(取模)问题。


1110. Power

Time Limit: 0.5 second
Memory Limit: 16 MB
You are given the whole numbers N, M and Y. Write a program that will find all whole numbers X in the interval [0, M−1] such that XN mod M = Y.

Input

The input contains a single line with N, M and Y (0 <  N < 999, 1 <  M < 999, 0 <  Y < 99) separated with one space.

Output

Output all numbers X separated with space on one line. The numbers must be written in ascending order. If no such numbers exist then output −1.

Sample

input output
2 6 4
2 4
Problem Source: Bulgarian National Olympiad Day #1

 解答如下:

 1  using  System;
 2 
 3  namespace  Skyiv.Ben.Timus
 4  {
 5     //   http://acm.timus.ru/problem.aspx?space=1 &num=1110
 6     sealed   class  T1110
 7    {
 8       static   void  Main()
 9      {
10         string [] ss  =  Console.ReadLine().Split();
11         int  n  =   int .Parse(ss[ 0 ]);
12         int  m  =   int .Parse(ss[ 1 ]);
13         int  y  =   int .Parse(ss[ 2 ]);
14         bool  ok  =   false ;
15         for  ( int  x  =   0 ; x  <  m; x ++ )
16        {
17           if  (ModPow(x, n, m)  ==  y)
18          {
19            ok  =   true ;
20            Console.Write(x  +   "   " );
21          }
22        }
23         if  ( ! ok) Console.Write( - 1 );
24      }
25    
26       static   int ModPow( int  x,  int  n,  int  m)
27      {
28         int  z  =   1 ;
29         for  ( int  i  =   0 ; i  <  n; i ++ ) z  =  (z  *  x)  %  m;
30         return  z;
31      }
32    }
33  }
34 

这里关键是 ModPow 方法。如果是 Pow 方法,以下实现比较高效:

1       static   int  Pow( int  x,  int  n)
2      {
3         int  z  =   1 ;
4         for  ( int  p  =  x; n  >   0 ; n  >>=   1 , p  *=  p)  if  ((n  &   1 !=   0 ) z  *=  p;
5         return  z;
6      }
7 

不过,Pow 方法很容易溢出,更适用于 x 和 z 是 BigInteger 的情形。 

根据3楼 guest 朋友的评论,可以将程序中第 26 到 31 行的 ModPow 方法改为以下更高效的代码:

     static   int  ModPow( int  x,  int  n,  int  m)
    {
      
int  z  =   1 ;
      
for  ( int  p  =  x; n  >   0 ; n  >>=   1 , p  =  (p  *  p)  %  m)  if  ((n  &   1 !=   0 ) z  =  (z  *  p)  %  m;
      
return  z;
    }

经测试,运行时间从原来的 0.14 秒降低到 0.125 秒。


返回目录

你可能感兴趣的:(po)