pojPseudoprime番号(高速電力)

説明

フェルマーの定理は、任意の素数のためと述べ  P  と任意の整数のために  A  > 1、  pは  =   (MOD  pは)。それは我々が上げる場合、ある   に  P 番目  による電力及び除算  P、余りがあります  いくつかの(しかし非常に多くはない)非プライム値  Pとして知られているが、ベース- いくつかのために、このプロパティ持って、擬似素数を  (カーマイケル数として知られており、一部には、ベース-がある すべてのための擬似素数  。)

2 <所与  P  ≤1000000000及び1 <   <  P、か否かを判断  pが  塩基である pseudoprime。

入力

入力が「0」を含む行に続いて、いくつかのテストケースが含まれています。各テストケースを含む行から成る  P  と 

出力

各テストケースのために、出力「YES」pが塩基である場合 pseudoprime。そうでない場合は、出力「ノー」。

サンプル入力

3 2 
10 3 
341 2 
341 3 
1105 2 
1105 3 
0 0

サンプル出力

いいえ
いいえ
はい
いいえ
はい
はい

この質問は、入力が2つの数字のp、出力はいpが素数とPOW(P)は%pでないときということを意味 ==、 それ以外の場合は出力がない
アイデア:基本的な限り、高速電力は、この質問に作ることができます。
高速電力:アイデアは、POW(P)= POW追加の複数の形態の複数にP 2のPOW(P)である (C1)* POW(C2)*を。 ... * POW(CN) 、ここで、p = C1 + C2 + ... + CN、 ビット演算子を使用して、
簡単にこの動作を実現することができます。

INT Fastpow(INT A、INT P){

Fastpow INT(A INT、INT P){
長いロングベースINT = A;
ロングロングINT RES = 1;
一方、(P){
(P 1)IF // pが最後の数字である場合、バイナリ表現のために、1真、そうでない場合はfalse
RES =ベース* / *、RES = RES%のMOD * /;
ベース* =ベース;
/ * BASE =ベースMOD%; * /
P >> 1;逆方向の// Pバイナリ表現1、ただのp除去する処理を、最後の1
}
の戻りRESを;
}

 

第二は、表現の高速再帰の力であります

Fastpow INT(INT A、Pはint){
IF(P == 1)を返す;
ロングロングFastpow INTのTEMP =(A、P / 2)%のPと、
IF(P%2 == 1)リターン* TEMPの一時% P *%pを、最初のpは間違った答えになる場合は、//ここでは省略し
、他のリターンのTEMP TEMP%の* pを;
}

 

最後に、ACコードを添付:

書式#include <iostreamの>
の#include <cstdioを>
std名前空間を使用しました。
長い長いint型のp;
INT Fastpow(int型、int型N){
長い長いint型M = N、基地=。
長い長いint型のres = 1;
一方、(M){
(M 1)であれば{
RESの=のRES *基地%のP。
}
基部=(ベース*ベース)%のP。
M >> = 1。
}
RESを返します。
}
/ * INT Fastpow(INT A、INTのN){
IF(N == 1)を返します。
長い長いINT TEMP = Fastpow(N / 2)%のP。
IF(N%2 == 1)戻り温度*一時%のP *%のP。
それ以外の戻り温度*一時%pを。
} * /
メインINT(){
長い長い、C [100000] INT。
一方、(〜のscanf( "%のLLDの%のLLD"、&P&A)){
IF(P == 0 && == 0)戻り0;
INTプラグ= 0。
ための式(I ++はint型、I = 2; iは<= P *)
(iは== 0のP%)= 1プラグ場合、
IF(プラグ== 0){
のprintf( "なしの\ n");
持続する;
}
// COUT << Fastpow(P)<< ENDL。
もし(Fastpow(P)== A)のprintf( "はい\ N");
他のprintf( "なし\ nを");
}
}

これは試作部門を使用して、素数最も基本的なものであるかどうかを判断、高速アルゴリズムは、少ない時間のかかる多くのもの上記以外をふるい素数を用いて以下に与えられます:

書式#include <iostreamの>
の#include <cstdioを>
する#include <CStringの>
名前空間stdを使用。
const int型MAXN = 31700;
constの長い長いint型maxn1 = 1E9 + 10。
INT Fastpow(INT A、INT P){
長いlong int型M = P、基地=。
長い長いint型のres = 1;
一方、(M){
(M 1)であれば{
RESの=のRES *基地%のP。
}
基部=(ベース*ベース)%のP。
M >> = 1。
}
RESを返します。
}
int型のmain(){
長い長いint型のP;
INT C [MAXN]、プリム[MAXN]、J = 0。
memset(C、0、はsizeof(c)参照)。
以下のために{(INT I = 2; iは++; iは<maxn1 *)
IF(C [I] == 0){
プリム[J] = I、J ++。
以下のために(int型K =私を*; MAXN <K、K + = I)
C [K] = - 1。
}
}
一方、(〜のscanf( "%のLLDの%のLLD"、&P&A)){
IF(P == 0 && == 0)戻り0;
INTプラグ= 1。
以下のために(INT i = 0; iはjを&&プリム[i]が<Pを<; iは++)
場合(P%のプリム[I] == 0)= 0プラグ。
IF(プラグ== 1){
のprintf( "なしの\ n");
持続する;
}
IF(Fastpow(P)== A)のprintf( "YESの\ n");
他のprintf( "なし\ nを");
}
}

おすすめ

転載: www.cnblogs.com/sunjianzhao/p/11461512.html