C ++
 Computer >> コンピューター >  >> プログラミング >> C ++

C++のModulop(Shanks Tonelliアルゴリズム)の下で平方根を見つけます


この問題では、2つの値nと素数pが与えられます。私たちの仕事は、モジュロpの下で平方根を見つけることです。

問題を理解するために例を見てみましょう

Input : n = 4, p = 11
Output : 9

ソリューションアプローチ

ここでは、Tonelli-Shanksアルゴリズムを使用します。 。

Tonelli-Shanksアルゴリズム x2 =n(mod p)の形式の合同で値xを解くために、モジュラー算術で使用されます。

シャンクスのトネリアルゴリズムを使用して平方根モジュロを見つけるアルゴリズム-

ステップ1 − $(n ^ {((p-1)/ 2)})(mod \:p)$の値を見つけます。その値がp -1の場合、モジュラー平方根は使用できません。

ステップ2 −次に、値p --1を(s * 2 e として使用します。 )。ここで、sは奇数で正であり、eは正です。

ステップ3 −値q ^((p-1)/ 2)(mod p)=-1

を計算します

ステップ4 − mが0より大きい場合はループを使用し、xの値を更新します。

b ^(2 ^ m)-1(mod p)となるようなmを見つけます。ここで0 <=m<=r-1。

Mが0の場合は、xを返します。それ以外の場合は、値を更新します。

x = x * (g^(2 ^ (r - m - 1))
b = b * (g^(2 ^ (r - m))
g = (g^(2 ^ (r - m - 1))
r = m

ソリューションの動作を説明するプログラム

#include <iostream>
#include <math.h>
using namespace std;
int powerMod(int base, int exponent, int modulus) {
   int result = 1;
   base = base % modulus;
   while (exponent > 0) {
      if (exponent % 2 == 1)
      result = (result * base)% modulus;
      exponent = exponent >> 1;
      base = (base * base) % modulus;
   }
   return result;
}
int gcd(int a, int b) {
   if (b == 0)
   return a;
   else
   return gcd(b, a % b);
}
int orderValues(int p, int b) {
   if (gcd(p, b) != 1) {
      return -1;
   }
   int k = 3;
   while (1) {
      if (powerMod(b, k, p) == 1)
      return k;
      k++;
   }
}
int findx2e(int x, int& e) {
   e = 0;
   while (x % 2 == 0) {
      x /= 2;
      e++;
   }
   return x;
}
int calcSquareRoot(int n, int p) {
   if (gcd(n, p) != 1) {
      return -1;
   }
   if (powerMod(n, (p - 1) / 2, p) == (p - 1)) {
      return -1;
   }
   int s, e;
   s = findx2e(p - 1, e);
   int q;
   for (q = 2; ; q++) {
      if (powerMod(q, (p - 1) / 2, p) == (p - 1))
      break;
   }
   int x = powerMod(n, (s + 1) / 2, p);
   int b = powerMod(n, s, p);
   int g = powerMod(q, s, p);
   int r = e;
   while (1) {
      int m;
      for (m = 0; m < r; m++) {
         if (orderValues(p, b) == -1)
         return -1;
         if (orderValues(p, b) == pow(2, m))
         break;
      }
      if (m == 0)
      return x;
      x = (x * powerMod(g, pow(2, r - m - 1), p)) % p;
      g = powerMod(g, pow(2, r - m), p);
      b = (b * g) % p;
      if (b == 1)
      return x;
      r = m;
   }
}
int main() {
   int n = 3;
   int p = 13;
   int sqrtVal = calcSquareRoot(n, p);
   if (sqrtVal == -1)
      cout<<"Modular square root is not exist";
   else
      cout<<"Modular square root of the number is "<<sqrtVal;
}

出力

Modular square root of the number is 9

  1. C++で汚染された二分木の要素を検索する

    二分木があるとします。そのツリーのルールは次のとおりです- root.val ==0 treeNode.valがxで、treeNode.leftがnullでない場合、treeNode.left.val =2 * x + 1 treeNode.valがxで、treeNode.rightがnullでない場合、treeNode.right.val =2 * x + 2 今、二分木が汚染されているので。これは、ツリーノードのすべての値が-1に変更されたことを示します。最初にバイナリツリーを回復してから、次のようにFindElementsクラスを実装する必要があります-

  2. 順序統計アルゴリズムを使用して、指定されたリストからi番目に大きい数を見つけるC++プログラム

    これは、Order-StatisticAlgorithmを使用して特定のリストからi番目に大きい数を見つけるC++プログラムです。 アルゴリズム Begin    function Insert() to insert nodes into the tree:    Arguments:       root, d.       Body of the function:       If tree is completely null then insert ne