トピック: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 == 0?1: - 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 。 }