📜  Python 3 中竞争性编程的数学技巧(1)

📅  最后修改于: 2023-12-03 14:45:55.543000             🧑  作者: Mango

Python 3 中竞争性编程的数学技巧

竞争性编程,特别是在算法竞赛中,需要程序员具备一定的数学基础和技巧。本文将介绍一些在 Python 3 中实现的竞争性编程数学技巧。

大整数运算

竞争性编程中,我们经常会遇到需要处理大整数的情况,而 Python 3 中提供了可处理任意大小的整数类型 int。例如,我们可以使用 ** 操作符计算任意大的幂:

>>> 123456789 ** 123456789
61793611876078221343934947204419175725756299048742389094436273784638593466904009104276928584750035084015986141679400600882187892606313350705023749680207056928399287635508490256380447593488609722806056429503660831047280657604347998726274796965042486495229112657509511436487659750996095562897576343119895937763441571916738035158680288582881906303202087284430902602714595488958447695838364748260124242866082042221372352840816378304498652038499215348208458849681242688116180512439771194707928850076057271364591529720148487922632582213944161493957753861352215031339896467710842957546530858243559738887318051352556260676856432695657090663220972147550580601301764977013811750123123788556808742781791387701981308501003449994755281733435981576951711946792342369694389711454239669031423425051284996380914178770938531260116820316713281137693026272392242231734932749833675023611479345605990217400540371409214326970024056179969301230535857845261108931960381497572710109625975959655686679364106457368837238863079729649538173047408423682098357935453268987521204147843700589698078483162290528777470769304989533059789715937195418130646844042565641607202934704209838437988741769370807518282751210945880582144333873483825245532961573208131756774614380384993751800372310705732295041455036944620576797197370355580423685523831492139606664363074083319155198691558965365085291987170105414288586223915190829326430339884921892072767121058148908713060901079811571855418325259783618044212629202950729471755862086989636442160721509899350804525328563809439426069510334464836666894750216089727165731314503144830759484443548829853990477612183478852607541047114735275817200132303332140663758268296718662620413975372332592868121189574204716659317705688941521609863163871910122631468414032451360524010433876692182438477950182600973187702529516855777697403673724027863387890016307653407862529048952451481171329291518265762622574897697084046721531864501840811954626146320559380921191410885033061352261781563596455354897944115820948138923022744742202616648063772650746549471871060154032789846218653311028704786240432344164970534252325570250192068893580535753017618617275673676059440549528465554896336199592306434624887164842374332696526213108172020567728252553227182137158211712825272670772165283191149303262339089456453921058823414265606245860216091728374076449855160413299812401812074865078620408704405008220205204665130981869467438036455240155724670264379720467824796138288734502934734943942212012801225739507937670434858007772290584229950419145136754347878469963811873806494039066241842848658398624978396190769352933177565571071414191036125607946077036035018108548335479015603153072862099338146533537699859648531797650512774336556143367794181499019446842955011038050699324623568181364242070366340755350361932017437954214866520108406138712125877178823678143756073223298583097967436473636073961781596346940206382444249751848076864155495893128972063193058840704291078848455597606021855878447889821918736786502205355526623645293481958313754075882785213011010902452893405433116742131499993899415391240651167831898889370273298250321227095656305819140853627032229135302993855062833984029384589984716697915050203532166368426425081519936639910319395209890317483258535930843818807634233005164827382266213738265515425275945282126632668957061781535292906972693968090536309030498028406707328674998952392546335430640924476875695248228047983209722379572512700
快速幂

快速幂是一种用于快速计算幂次的算法。在 Python 3 中,可以使用递归或循环来实现快速幂。以下是使用递归实现的 Python 3 代码:

def pow(x, n):
    if n == 0:
        return 1
    elif n % 2 == 0:
        y = pow(x, n // 2)
        return y * y
    else:
        y = pow(x, (n - 1) // 2)
        return y * y * x

该算法的时间复杂度为 $O(\log n)$。

高精度除法

在竞争性编程中,我们有时需要计算高精度除法。以下是使用 Python 3 实现的高精度除法算法:

def divide(a, b):
    if len(a) < len(b) or (len(a) == len(b) and a < b):
        return '0'
    res = [0] * (len(a) - len(b) + 1)
    b = b + '0' * (len(a) - len(b))
    for i in range(len(a) - len(b), -1, -1):
        tmp = b
        cnt = 0
        while a[i:i + len(tmp)] >= tmp:
            a[i:i + len(tmp)] = list(map(int, a[i:i + len(tmp)]))
            tmp = list(map(int, tmp))
            a[i:i + len(tmp)] = [x - y for x, y in zip(a[i:i + len(tmp)], tmp)]
            a[i:i + len(tmp)] = list(map(str, a[i:i + len(tmp)]))
            tmp = list(map(str, tmp))
            cnt += 1
        res[i] = cnt
        b = b[1:]
    return ''.join(str(i) for i in res).lstrip('0')

该算法的时间复杂度为 $O(n^2)$。

素数筛法

素数在竞争性编程中是一个经常使用的概念。下面是使用 Python 3 实现的筛法素数算法:

def sieve_of_eratosthenes(n):
    is_prime = [True] * (n + 1)
    is_prime[0] = is_prime[1] = False
    for i in range(2, int(n ** 0.5) + 1):
        if is_prime[i]:
            for j in range(i * i, n + 1, i):
                is_prime[j] = False
    return [i for i in range(n + 1) if is_prime[i]]

该算法的时间复杂度为 $O(n \log \log n)$。

最大公约数与最小公倍数

在竞争性编程中,计算最大公约数(GCD)和最小公倍数(LCM)是一个经常使用的操作。以下是使用 Python 3 实现的 GCD 和 LCM 算法:

def gcd(x, y):
    if y == 0:
        return x
    else:
        return gcd(y, x % y)

def lcm(x, y):
    return (x * y) // gcd(x, y)

这些算法的时间复杂度都很低,并且 Python 3 提供了内置函数 math.gcd() 来计算 GCD。

斐波那契数列

斐波那契数列在竞争性编程中也是一个经常使用的概念。以下是使用 Python 3 实现的斐波那契数列算法:

def fibonacci(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fibonacci(n - 1) + fibonacci(n - 2)

这个算法的时间复杂度为 $O(2^n)$,更高效的实现方法是使用迭代或矩阵乘法。