[Python] How to derive nCk (ABC156-D)

Note that it was needed at ABC156-D.

https://atcoder.jp/contests/abc156/tasks/abc156_d

If you implement it without thinking

nC_k = \frac{n!}{(n-k)!k!}

The definition of $ nC_k $ is ↑, so if you write this as it is in the code,

import math
def comb(n,k):
    math.factorial(n) // (math.factorial(n - k) * math.factorial(k))

print(comb(4,2))
# 6

It looks like this. However, $ n! $ Is $ O (n) $, so in the case of $ n \ leqq10 ^ 9 $ like ABC156-D this time, the calculation time becomes long and it is not in time. I have to shorten the calculation time somehow.

Prerequisite knowledge

First you need to know the iterative squares method and Fermat's little theorem.

Repeated squares

How to find exponentiation at high speed. In python you can calculate the remainder of $ x ^ n $ divided by $ mod $ by using pow (x, n, mod).

Fermat's Little Theorem

When $ p $ is a prime number and $ a $ is an integer that is not a multiple of $ p $ ($ a $ and $ p $ are relatively prime), the following holds.

a^{p-1} \equiv 1 (mod\, p)

The point is that if you divide $ a ^ {p-1} $ by $ p $, it's too much.

Transform nCk

$ nC_k $ can be transformed as follows.

nC_k = \frac{n!}{(n-k)!k!}=\frac{n(n-1)(n-2)\cdots(n-k+1)}{k!}

Now pay attention to $ \ frac {1} {k!} $.

From Fermat's Little Theorem

a^{p-1} mod\, p = 1 \\ \\
a^{p-2} mod\, p = \frac{1}{a} \\

You get $ a ^ {p-2} mod , p = \ frac {1} {a} $. Therefore, $ \ frac {1} {k!} = K! ^ {P-2} mod , p $ holds, and $ k! ^ {p-2} $ can be calculated at high speed by the iterative square method. , $ \ Frac {1} {k!} $ can be calculated at high speed.

From the above, $ nC_k $ can be expressed as follows.

nC_k = n(n-1)\cdots(n-k+1) \times(k!^{p-2}\,mod\,p)

The amount of calculation is $ O (k) . ( K! $ Takes the longest)

Implementation

# O(k)
def comb(n,k):
    nCk = 1
    MOD = 10**9+7

    for i in range(n-k+1, n+1):
        nCk *= i
        nCk %= MOD

    for i in range(1,k+1):
        nCk *= pow(i,MOD-2,MOD)
        nCk %= MOD
    return nCk

print(comb(4,2))
# 6

reference

https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A7%E3%83%AB%E3%83%9E%E3%83%BC%E3%81%AE%E5%B0%8F%E5%AE%9A%E7%90%86 https://note.com/tanon_cp/n/ncff944647054

Recommended Posts

[Python] How to derive nCk (ABC156-D)
How to install Python
How to install python
[2020.8 latest] How to install Python
How to install Python [Windows]
python3: How to use bottle (2)
[Python] How to use list 1
How to update Python Tkinter to 8.6
How to use Python argparse
Python: How to use pydub
[Python] How to use checkio
How to run Notepad ++ Python
How to change Python version
How to develop in Python
[python] How to judge scalar
[Python] How to use input ()
How to use Python lambda
[Python] How to use virtualenv
python3: How to use bottle (3)
python3: How to use bottle
How to use Python bytes
How to install python using anaconda
How to write a Python class
[Python] How to FFT mp3 data
Python: How to use async with
[Python] How to use Pandas Series
How to collect images in Python
How to use Requests (Python Library)
How to use SQLite in Python
[Introduction to Python] How to parse JSON
How to get the Python version
How to get started with Python
[Python] How to import the library
[Python] How to use list 3 Added
How to use Mysql in python
How to use OpenPose's Python API
[Python] How to swap array values
How to wrap C in Python
How to use ChemSpider in Python
How to use FTP with Python
Python: How to use pydub (playback)
How to use PubChem in Python
How to speed up Python calculations
How to calculate date with python
How to access wikipedia from python
[Python] ABC175D
How to use python zip function
[Nanonets] How to post Memo [Python]
How to handle Japanese in Python
[Python] How to use Typetalk API
How to package and distribute Python scripts
[Introduction to Python] How to use class in Python?
How to read pydoc on python interpreter
[Python] How to display random numbers (random module)
How to dynamically define variables in Python
How to install and use pandas_datareader [Python]
[Python] How to make a class iterable
How to do R chartr () in Python
python notes: Modularization: __name__ == How to use'__main__'
python3 How to install an external module
[Kivy] How to install Kivy on Windows [Python]