guest@itl:~/home/algebra$
templates/modular-arithmetic-helpers.cpp
compilable
$cat templates/modular-arithmetic-helpers

Modular Arithmetic Helpers

Safe modular add, multiply, binary exponentiation, Russian peasant multiplication, and big mod.

[Algebra]|
Jul 9, 2026
|explanatory_notes.md|
#modular#binpow#int128#overflow-safe
Log in to track progress, save custom versions, and organize into collections.Log In
$cat source_code/
cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

void addMod(ll& a, ll b, ll mod) { a = (a + b % mod + mod) % mod; }

void mulMod(ll& a, ll b, ll mod) { a = ((__int128)a * b) % mod; }

ll binpow(ll b, ll e, ll mod) {
  ll res = 1;
  b %= mod;
  while (e > 0) {
    if (e & 1) res = ((__int128)res * b) % mod;
    b = ((__int128)b * b) % mod;
    e >>= 1;
  }
  return res;
}

ll binpow(ll b, ll e) {
  ll res = 1;
  while (e > 0) {
    if (e & 1) res *= b;
    b *= b;
    e >>= 1;
  }
  return res;
}

ll binaryMul(ll a, ll b, ll mod) {
  ll res = 0;
  a %= mod;
  while (b > 0) {
    if (b & 1) {
      res += a;
      if (res >= mod) res -= mod;
    }
    a += a;
    if (a >= mod) a -= mod;
    b >>= 1;
  }
  return res;
}

ll bigMod(const string& s, ll mod) {
  ll res = 0;
  for (char c : s) res = (res * 10 + (c - '0')) % mod;
  return res;
}
49 linesutf-8
$cat explanation_notes.md
notes_viewer --renderedmarkdown (math enabled)

Modular Arithmetic Helpers

Functions

  • addMod(a, b, mod) — adds bb to aa under mod, handles negative bb

  • mulMod(a, b, mod) — multiplies using (__int128) to avoid overflow

  • binpow(b, e, mod) — binary exponentiation bemodmb^e \bmod m in O(loge)O(\log e), uses (__int128)

  • binpow(b, e) — same without mod (watch for overflow)

  • binaryMul(a, b, mod) — overflow-safe multiplication via repeated doubling, O(logb)O(\log b). Use when __int128 isn't available

  • bigMod(s, mod) — computes huge number (string input) mod mm, digit by digit
  • __int128 vs binaryMul

  • __int128 — constant time multiply, preferred default

  • binaryMulO(logb)O(\log b) but portable to all judges
  • When to Use

  • DP/counting with intermediate overflow risk

  • Modular inverse via Fermat: a1ap2(modp)a^{-1} \equiv a^{p-2} \pmod{p}

  • String-encoded large numbers mod something
  • Complexity

  • addMod / mulMod — O(1)O(1)

  • binpow — O(loge)O(\log e)

  • binaryMul — O(logb)O(\log b)

  • bigMod — O(s)O(|s|)