web-dev-qa-db-ja.com

mod 1000000007の質問で助けが必要

私は数学が苦手で、常に素数を法とする答えを必要とする問題に悩まされています。

例:(500!/ 20!)mod 1000000007

私はBigIntegersに精通していますが、(DPを使用した後でも)500の階乗を計算した後にモジュロを計算すると、負荷がかかるようです。

このような問題に対処する特定の方法があるかどうか知りたいのですが。

ここで私が現在解決しようとしているそのような問題の1つを示します。 http://www.codechef.com/FEB12/problems/WCOUNT

誰かが私にこれらのコーディングの問題を処理するためのチュートリアルまたはアプローチに導くことができれば、それは本当に役に立ちます。 JavaおよびC++に精通しています。

28
daerty0153

これらの多数のモジュラスタスクの鍵は、モジュラスを実行する前に完全な結果を計算することではありません。 数値を小さく保つために、中間ステップで係数を減らす必要があります:

500! / 20! = 21 * 22 * 23 * ... * 500

21 * 22 * 23 * 24 * 25 * 26 * 27 = 4475671200

4475671200 mod 1000000007 = 475671172
475671172 * 28 mod 1000000007 = 318792725
318792725 * 29 mod 1000000007 = 244988962
244988962 * 30 mod 1000000007 = 349668811

...

 31768431 * 500 mod 1000000007 = 884215395

500! / 20! mod 1000000007 = 884215395

すべてのステップでモジュラスを減らす必要はありません。数値が大きくなりすぎないように、十分な頻度で実行してください。


longの最大値は2 ^ 63-1であることに注意してください。したがって、2つの正の整数値(つまり、オペランドの1つがlong)間で64ビット乗算を実行しても、オーバーフローしませんlong。残りの操作を安全に実行できます%その後(それが正の場合も同様)、必要に応じて整数にキャストバックします。

52
Mysticial

まず、500!/20!は、21から500までのすべての数値の積です。次に、%1000000007各操作の最後。これでプログラムを作成できるはずです。数値がオーバーフローしないように注意してください。32ビットでは不十分な場合があります。

7
dasblinkenlight

これはあなたのために役立つと思います

for(mod=prime,res=1,i=20;i<501;i++)
{
res*=i; // an obvious step to be done 
if(res>mod) // check if the number exceeds mod
res%=mod; // so as to avoid the modulo as it is costly operation 
}
5
MissingNumber