私は50,000の数字(0〜50,000の範囲)を持っています。そして、私は(これらの数字の積)MOD 1000000007が必要です。次のコードはそれほど簡単ではありません。 「分割して克服する」テクニックについて聞いたことがありますが、どのように実装するかはわかりません。perlで非常に大きな数値を高速に乗算する
$ans *= ($_ % 1000000007) foreach @array;
$ans %= 1000000007;
お勧めします。
私は50,000の数字(0〜50,000の範囲)を持っています。そして、私は(これらの数字の積)MOD 1000000007が必要です。次のコードはそれほど簡単ではありません。 「分割して克服する」テクニックについて聞いたことがありますが、どのように実装するかはわかりません。perlで非常に大きな数値を高速に乗算する
$ans *= ($_ % 1000000007) foreach @array;
$ans %= 1000000007;
お勧めします。
アレイのすべての番号で$_ % 1000000007
を実行しますが、最後に$ans %= 1000000007
を実行するまで、$ans
は非常に大きくなる可能性があります。
foreach my $number (@array)
{
$ans *= ($number % 1000000007);
$ans %= 1000000007;
}
'($ number%1000000007)'を省略し、 '$ ans * = $ number'だけすることができます。数字は50,000までです(さらに大きい数字の場合でも%を2回行う理由はありません)。 – ugoren
@array
内のすべての値が範囲0内にある場合$num % 1000000007
の結果は常に少ない1000000007.よりだから、すべての値について$num
になります... 50,000、こうした:私は次のことを提案し、これを修正するには
計算は冗長です。あなたは、2つのステップを行う必要はなく、*=
演算子使用します。しかし、注意の
$ans = ($ans % 1000000007) * $_ for @array;
Wordを。非プライムモジュロの場合、常にモジュロ演算の結果がゼロになるというリスクがありますが、乗算全体がゼロになることはもちろんです。私は1000000007が素数であるように思われるので、あなたはすでにこれを考えていたと思いますが、とにかく言及します。
ETA:中間製品の再利用:あなたがここに演算子を配合する必要はありません
for (@array) {
$ans *= $_;
print "Before mod: $ans\n";
$ans %= 1000000007;
print "After mod : $ans\n";
}
注意。
計算上の再利用が重要/期待される場合(TLPの回答へのコメントに記載されているように)、関数をメモすると、以前に計算された結果を効果的に記憶することでスピードアップに役立ちます。
を参照してください@のarray' '内のすべての数は、<50,000の場合はそれが乗算前に計算されているので、その後、' $ _%1000000007'は、何も変更されません。 – TLP