224電卓(BSGSアルゴリズム)パンチをAcWing

トピック:https://www.acwing.com/problem/content/226/

質問の意味:3つの機能を完了するために電卓があります

1、所与Y、Z、P、算出YはZ M O D Pの YZModPの値。

図2に示すように、与えられたY、Z、Pは、満足するように算出されるX Y Z m個のOのDのP の最小非負整数のxY≡Z(MOD P)を、

図3に示すように、与えられたY、Z、Pは、満たすために計算されるY X Z m個のOのDのP の最小非負整数のYx≡Z(MOD P)を。

アイデアは:pは素数であるため、最初は明らかに、第二、迅速なパワーを法であるので、我々はすぐに逆元を取るために、電力を計算することができ、ボードの3分の1がBSGSです

#include <cstdioを> 
する#include <CStringの> 
する#include <cmath> 
の#include <地図> 
の#include <iostreamの> 
する#include <アルゴリズム>
 使用して 名前空間STDを、
#define LL長い長
 の#defineっ長い長い
 // 快速幂求A ^ Bの
LLパワー(LL、LLのB、LL n)で
{ 
    LL S = 1 一方、(b)は、
    { 
        もし、(B&1 
            S =(S * A)%N。=(* A)%N。
        B = B >> 1; 
    } 
    戻りS。
} 
のLL WORK2(LLのY、LLのZ、LL P)// X-Y = Z MOD P 
{
     場合(Yの%のp == 0 && Z =!0リターン - 1 戻り Z *パワー(Y、P 2、P)%のPと、
} 
のLL BSGS(-1,11,11-のB、LLのP){ 
    マップ <-1,11,11-> ハッシュ。
    hash.clear(); 
    B%= P。
    LL T =(LL)SQRT(P)+ 1 INT J = 0 ; J <T、J ++ ){ 
        LLヴァル=(LL)*パワー(J、P)%のB 、P。
        【ヴァル]ハッシュ = jで、
    } 
    A = 力(T、P)。
    もし(== 0リターンのb == 01: - 1 以下のためにint型 i = 0 ; I <= T; iは++ ){ 
        LLヴァル = 電源(I、P)。
        LL用J = hash.find(ヴァル)== hash.end() - ?1 :ハッシュ[ヴァル]。
        場合(J> = 0 && iはTJ> = * 0のリターンを私はTJを* ; 
    }
    戻る - 1 
} 
int型のmain()
{ 
    LL、B、T、N。
    LLオペアンプ; 
    scanf関数(" %のLLDの%のLLD "、&​​T、&OP)。
    以下のためにint型 i = 0 ; iはTを<I ++は{)
        のscanf(" %LLD%LLD%LLD "、&​​、&B、&n)を。
        もし(OPの== 1 ){ 
            のprintf(" %LLDする\ n " 、電源(B、N))。
        } 
        そう であれば(オペアンプ== 2 ){ 
            W LL =WORK2(B、N)。
            もし(== W - 1)のprintf(" ORZ、私はXを見つけることができません\ N!" );
            のprintf(" %LLDの\ nを" 、ワット); 
        } 
        そう であれば(OP == 3 ){ 
            W LL = BSGS(B、N)。
            もし(== W - 1)のprintf(" ORZ、私はXを見つけることができません\ N!" );
            のprintf(" %LLDの\ nを" 、ワット); 
        } 
    } 
    戻り 0 
}

 

おすすめ

転載: www.cnblogs.com/Lis-/p/11290502.html