Language: C++

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using int_t = long long;
constexpr int_t BASE = 100000000 * 100000000, LEN = 16;
class bigint {
private:
    bool negative;
    std::vector<int_t> a;
    bigint& normalize();
public:
    bigint(int_t x = 0);
    bigint(const std::string& s);
    bigint& operator = (const bigint& x);
    bigint& operator = (int_t x);
    bigint& operator = (const std::string& s);
    const bool operator < (const bigint& x) const;
    const bool operator > (const bigint& x) const;
    const bool operator <= (const bigint& x) const;
    const bool operator >= (const bigint& x) const;
    const bool operator != (const bigint& x) const;
    const bool operator == (const bigint& x) const;
    bigint operator -() const;
    bigint& operator += (const bigint& x);
    bigint& operator -= (const bigint& x);
    bigint& operator *= (const bigint& x);
    bigint& operator /= (const bigint& x);
    bigint& operator %= (const bigint& x);
    const bigint operator + (const bigint& x) const;
    const bigint operator - (const bigint& x) const;
    const bigint operator * (const bigint& x) const;
    const bigint operator / (const bigint& x) const;
    const bigint operator % (const bigint& x) const;
    friend std::pair<bigint, bigint> divmod(const bigint& lhs, const bigint& rhs);
    friend std::istream& operator >> (std::ostream& is, bigint& x); //??????????£?
    friend std::ostream& operator << (std::ostream& os, const bigint& x);
    friend const bigint abs(bigint x);
};
inline bigint& bigint::normalize() {
    int i = a.size() - 1;
    while (i >= 0 && a[i] == 0) --i;
    a.resize(i + 1);
    if (a.size() == 0) negative = false;
    return *this;
}
inline bigint::bigint(int_t x) : negative(x < 0) {
    x = abs(x);
    for (; x > 0; x /= BASE) a.push_back(x % BASE);
}
inline bigint::bigint(const std::string& s) : negative(false) {
    int p = 0;
    if (s[p] == '-') { ++p; negative = true; }
    else if (s[p] == '+') { ++p; }
    for (int i = s.size() - 1, v = BASE; i >= p; --i, v *= 10) {
        int x = s[i] - '0';
        if (x < 0 || 9 < x) {
            std::cerr << "error: parse error:" << s << std::endl;
            exit(1);
        }
        if (v == BASE) {
            v = 1;
            a.push_back(x);
        }
        else a.back() += (x)*v;
    }
    normalize();
}
inline bigint& bigint::operator = (const bigint& x) {
    negative = x.negative;
    a = x.a;
    return *this;
}
inline bigint& bigint::operator = (int_t x) { return *this = bigint(x); }
inline bigint& bigint::operator = (const std::string& s) { return *this = bigint(s); }
inline const bool bigint::operator < (const bigint& x) const {
    if (negative != x.negative) return negative > x.negative;
    if (a.size() != x.a.size()) return (a.size() < x.a.size()) ^ negative;
    for (int i = a.size() - 1; i >= 0; --i)
        if (a[i] != x.a[i]) return (a[i] < x.a[i]) ^ negative;
    return false;
}
inline const bool bigint::operator > (const bigint& x) const { return x<(*this); }
inline const bool bigint::operator <= (const bigint& x) const { return !(x<(*this)); }
inline const bool bigint::operator >= (const bigint& x) const { return !((*this)<x); }
inline const bool bigint::operator != (const bigint& x) const { return (*this)<x || x<(*this); }
inline const bool bigint::operator == (const bigint& x) const { return !((*this)<x || x<(*this)); }
inline bigint bigint::operator -() const {
    bigint ret(*this);
    if (a.size()) ret.negative = !ret.negative;
    return ret;
}
inline bigint& bigint::operator += (const bigint& x) {
    if (negative != x.negative) return *this -= -x;
    if (a.size() < x.a.size()) a.resize(x.a.size());
    int_t tmp = 0;
    for (int i = 0; i < a.size(); ++i) {
        a[i] += (i<x.a.size() ? x.a[i] : 0) + tmp;
        tmp = a[i] / BASE;
        a[i] %= BASE;
    }
    if (tmp) a.push_back(1);
    return *this;
}
inline bigint& bigint::operator -= (const bigint& x) {
    if (negative != x.negative) return *this += -x;
    std::vector<int_t> b(x.a);
    if ((*this < x) ^ negative) {
        a.swap(b);
        negative = !negative;
    }
    int_t tmp = 0;
    for (int i = 0; i < a.size(); ++i) {
        a[i] += BASE - (i<b.size() ? b[i] : 0) + tmp;
        tmp = a[i] / BASE - 1;
        a[i] %= BASE;
    }
    return this->normalize();
}
inline bigint& bigint::operator *= (const bigint& x) {
    negative ^= x.negative;
    std::vector<int_t> c(a.size()*x.a.size() + 1);
    for (int i = 0; i < a.size(); ++i) {
        long long tmp = 0;
        for (int j = 0; j < x.a.size(); ++j) {
            long long v = (long long)a[i] * x.a[j] + c[i + j] + tmp;
            tmp = v / BASE;
            c[i + j] = (int_t)(v % BASE);
        }
        if (tmp) c[i + x.a.size()] += (int_t)tmp;
    }
    a.swap(c);
    return this->normalize();
}
inline bigint& bigint::operator /= (const bigint& x) {
    return *this = divmod(*this, x).first;
}
inline bigint& bigint::operator %= (const bigint& x) {
    return *this = divmod(*this, x).second;
}
inline const bigint bigint::operator + (const bigint& x) const {
    bigint res(*this); return res += x;
}
inline const bigint bigint::operator - (const bigint& x) const {
    bigint res(*this); return res -= x;
}
inline const bigint bigint::operator * (const bigint& x) const {
    bigint res(*this); return res *= x;
}
inline const bigint bigint::operator / (const bigint& x) const {
    bigint res(*this); return res /= x;
}
inline const bigint bigint::operator % (const bigint& x) const {
    bigint res(*this); return res %= x;
}
inline std::pair<bigint, bigint> divmod(const bigint& lhs, const bigint& rhs) {
    if (!rhs.a.size()) {
        std::cerr << "error: division by zero" << std::endl;
        exit(1);
    }
    bigint x(abs(rhs)), q, r;
    for (int i = lhs.a.size() - 1; i >= 0; --i) {
        r = r * BASE + lhs.a[i];
        int head = 0, tail = BASE;
        if (r >= x) {
            while (head + 1 < tail) {
                int_t mid = (head + tail) / 2;
                if (x * bigint(mid) > r) tail = mid;
                else head = mid;
            }
            r -= x * head;
        }
        q.a.push_back(head);
    }
    reverse(q.a.begin(), q.a.end());
    bool neg = lhs.negative ^ lhs.negative;
    q.negative = neg; r.negative = neg;
    return std::make_pair(q.normalize(), r.normalize());
}
inline std::istream& operator >> (std::istream& is, bigint& x) {
    std::string tmp; is >> tmp;
    x = bigint(tmp);
    return is;
}
inline std::ostream& operator << (std::ostream& os, const bigint& x) {
    if (x.negative) os << '-';
    if (!x.a.size()) os << 0;
    else os << x.a.back();
    for (int i = x.a.size() - 2; i >= 0; --i) {
        os.width(LEN);
        os.fill('0');
        os << x.a[i];
    }
    return os;
}
inline const bigint abs(bigint x) {
    x.negative = false;
    return x;
}

using namespace std;

int main() 
{
    int n, m, r;
    while (cin >> n >> m >> r) 
    {
        int x = r - n*m + n - 1;
        int y = r - m * n;
        bigint ans;
        if (y < 0 || x < 0) {
            ans = 0;
        }
        else
        {
            ans = 1;
            for (int i = 1; i <= y; i = i + 1) 
            {
                ans = ans * (x - i + 1);
                ans = ans / i;
            }
        }
        cout << ans << endl;
    }
}

Compiler output:
a.cc:7:34: warning: integer overflow in expression of type 'int' results in '1874919424' [-Woverflow]
    7 | constexpr int_t BASE = 100000000 * 100000000, LEN = 16;
      |                        ~~~~~~~~~~^~~~~~~~~~~
a.cc:7:34: error: overflow in constant expression [-fpermissive]
a.cc:7:36: error: overflow in constant expression [-fpermissive]
    7 | constexpr int_t BASE = 100000000 * 100000000, LEN = 16;
      |                                    ^~~~~~~~~