Problem:
問題 5
IOI 宝飾店ではビーズのネックレスを売り出すことになった．
ビーズは n 色あり，
これらをそれぞれ m 個以上ずつ選んで r 個のビーズからなるネックレスとし，
１つずつ化粧箱に入れて販売したい．
色の組合せが違うものをすべて１つずつ用意したいが，
化粧箱を何個用意したらよいか店員の誰もわからない．
n, m, r によっては現実的でない個数の化粧箱が必要となるのではないかと店長は心配している．
IOI 宝飾店の店長に代わって，
必要な化粧箱の個数を出力するプログラムを作成しなさい．
n, m, r は整数で，0≦m＜n≦r≦10000 である．
入力ファイルは１行で，
空白を区切りとして n, m, r がこの順に書いてある．
入力ファイル５つのうちの３つでは n≦10 である．
出力ファイルにおいては，
出力の最後の行にも改行コードを入れること．
入出力例
入力例１
2 0 3
出力例１
4
入力例２
3 1 4
出力例２
3
入力例３
4 2 5
出力例３
0
問題文と自動審判に使われるデータは、
情報オリンピック日本委員会
が作成し公開している問題文と採点用テストデータです。

Submitted solutions:

code_snippet: #include <cstdio>
#include <cstring>
#define BASE (1000000)
typedef long long lint;
int main() {
  int n, m, r;
  int head, tail;
  int i, j;
  static lint ans[20000], temp[20000];
  lint carry;
  tail = sizeof(ans) / sizeof(lint) - 1;
  scanf("%d%d%d", &n, &m, &r);
  if (r - m * n < 0 || n + r - m * n - 1 < 0) {
    printf("0\n");
  } else {
    head = tail;
    ans[tail] = 1;
    for (i = 1; i <= n + r - m * n - 1; i++) {
      carry = 0;
      for (j = tail; j >= head; j--) {
        carry += i * ans[j];
        ans[j] = carry % BASE;
        carry /= BASE;
      }
      while (carry != 0) {
        ans[--head] = carry % BASE;
        carry /= BASE;
      }
    }
    for (i = r - m * n; i >= 2; i--) {
      memcpy(temp, ans, sizeof(ans));
      carry = 0;
      for (j = head; j <= tail; j++) {
        carry = carry * BASE + temp[j];
        ans[j] = carry / i;
        carry %= i;
      }
    }
    for (i = n - 1; i >= 2; i--) {
      memcpy(temp, ans, sizeof(ans));
      carry = 0;
      for (j = head; j <= tail; j++) {
        carry = carry * BASE + temp[j];
        ans[j] = carry / i;
        carry %= i;
      }
    }
    while (ans[head] == 0) {
      head++;
    }
    for (i = head; i <= tail; i++) {
      if (i != head) {
        printf("%06lld", ans[i]);
      } else {
        printf("%lld", ans[i]);
      }
    }
    printf("\n");
  }
  return (0);
}
accuracy: 1
time_ms: 3170
memory_kb: 2952
final_rank: 8

code_snippet: #include <cstdio>
#include <cstring>
#define BASE (1000000)
typedef long long lint;
int main() {
  int n, m, r;
  int head, tail;
  int i, j;
  static lint ans[20000], temp[20000];
  lint carry;
  tail = sizeof(ans) / sizeof(lint) - 1;
  scanf("%d%d%d", &n, &m, &r);
  if (r - m * n < 0 || n + r - m * n - 1 < 0) {
    printf("0\n");
  } else {
    head = tail;
    ans[tail] = 1;
    for (i = n; i <= n + r - m * n - 1; i++) {
      carry = 0;
      for (j = tail; j >= head; j--) {
        carry += i * ans[j];
        ans[j] = carry % BASE;
        carry /= BASE;
      }
      while (carry != 0) {
        ans[--head] = carry % BASE;
        carry /= BASE;
      }
    }
    for (i = r - m * n; i >= 2; i--) {
      memcpy(temp, ans, sizeof(ans));
      carry = 0;
      for (j = head; j <= tail; j++) {
        carry = carry * BASE + temp[j];
        ans[j] = carry / i;
        carry %= i;
      }
    }
    while (ans[head] == 0) {
      head++;
    }
    for (i = head; i <= tail; i++) {
      if (i != head) {
        printf("%06lld", ans[i]);
      } else {
        printf("%lld", ans[i]);
      }
    }
    printf("\n");
  }
  return (0);
}
accuracy: 1
time_ms: 870
memory_kb: 2960
final_rank: 3

code_snippet: #include <bits/stdc++.h>
#include <boost/multiprecision/cpp_int.hpp>
using namespace std;

boost::multiprecision::cpp_int combination(long long int a,long long int b){
    boost::multiprecision::cpp_int ans=1;
    b=min(b,a-b);
    for(int i=0;i<b;i++){
        ans*=a-b+i+1;
        ans/=i+1;
    }
    return ans;
}

int main(){
    long long n,m,r;
    cin>>n>>m>>r;
    r-=n*m;
    if(r<0){
        cout<<0<<endl;
        return 0;
    }
    cout<<combination(r+n-1,n-1)<<endl;
}
accuracy: 1
time_ms: 100
memory_kb: 3228
final_rank: 2

code_snippet: #include <iostream>
using namespace std;

long long solve(long long n, long long r);

int main(void){
  long long n,m,r;
  cin>>n>>m>>r;
  r-=n*m;
  if(r<0){
    cout<<0<<endl;
    return 0;
  }
  cout<<solve(n,r)<<endl;
  return 0;
}


long long solve(long long n, long long r){
  long long** table = new long long* [n+10];
  for(long long i=0;i<n+10;i++){
    table[i] = new long long[r+10];
    for(long long j=0;j<r+10;j++){
      table[i][j]=0;
    }
  }
  for(long long j=0;j<r+1;j++){
    table[1][j]=1;
  }
  for(long long i=0;i<n+1;i++){
    table[i][0]=1;
  }
  for(long long i=1;i<n+1;i++){
    for(long long j=1;j<r+1;j++){
      table[i][j]=1;
      for(long long k=0;k<j;k++){
        table[i][j]+=table[i-1][j-k];
      }
    }
  }
  /*
  for(long long i=0;i<n+1;i++){
    for(long long j=0;j<r+1;j++){
      cout<<table[i][j]<<"\t";
    }
    cout<<endl;
  }
  */
  return table[n][r];
}
accuracy: 0.6
time_ms: 200
memory_kb: 11072
final_rank: 18

code_snippet: // includes
#include <bits/stdc++.h>
using namespace std;

// macros
#define pb emplace_back
#define mk make_pair
#define FOR(i, a, b) for(int i=(a);i<(b);++i)
#define rep(i, n) FOR(i, 0, n)
#define rrep(i, n) for(int i=((int)(n)-1);i>=0;i--)
#define irep(itr, st) for(auto itr = (st).begin(); itr != (st).end(); ++itr)
#define irrep(itr, st) for(auto itr = (st).rbegin(); itr != (st).rend(); ++itr)
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end())
#define bit(n) (1LL<<(n))
// functions
template <class T>bool chmax(T &a, const T &b){if(a < b){a = b; return 1;} return 0;}
template <class T>bool chmin(T &a, const T &b){if(a > b){a = b; return 1;} return 0;}
template <typename T> istream &operator>>(istream &is, vector<T> &vec){for(auto &v: vec)is >> v; return is;}
template <typename T> ostream &operator<<(ostream &os, const vector<T>& vec){for(int i = 0; i < vec.size(); i++){ os << vec[i]; if(i + 1 != vec.size())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const set<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const unordered_set<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const multiset<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const unordered_multiset<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T1, typename T2> ostream &operator<<(ostream &os, const pair<T1, T2> &p){os << p.first << " " << p.second; return os;}
template <typename T1, typename T2> ostream &operator<<(ostream &os, const map<T1, T2> &mp){for(auto itr = mp.begin(); itr != mp.end(); ++itr){ os << itr->first << ":" << itr->second; auto titr = itr; if(++titr != mp.end())os << " "; } return os;}
template <typename T1, typename T2> ostream &operator<<(ostream &os, const unordered_map<T1, T2> &mp){for(auto itr = mp.begin(); itr != mp.end(); ++itr){ os << itr->first << ":" << itr->second; auto titr = itr; if(++titr != mp.end())os << " "; } return os;}
//  types
using ll = long long int;
using P = pair<int, int>;
// constants
const int inf = 1e9;
const ll linf = 1LL << 50;
const double EPS = 1e-10;
const int mod = 1000000007;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, -1, 0, 1};
// io
struct fast_io{
  fast_io(){ios_base::sync_with_stdio(false); cin.tie(0); cout << fixed << setprecision(20);}
} fast_io_;

using cd = complex<double>;
// f.size() should be the power of 2.
void rec_fft(vector<cd> &f, bool inv=false){
  int n = f.size();
  if(n == 1)return;
  vector<cd> f0(n / 2), f1(n / 2);
  for(int i = 0; i < n / 2; i++){
    f0[i] = f[i * 2];
    f1[i] = f[i * 2 + 1];
  }
  rec_fft(f0, inv);
  rec_fft(f1, inv);
  double th = M_PI * 2 / n;
  if(inv)th = - th;
  cd u(cos(th), sin(th)), ui(1, 0);
  for(int i = 0; i < n; i++){
    f[i] = f0[i%(n/2)] + ui * f1[i%(n/2)];
    ui = ui * u;
  }
}

// f.size() should be the power of 2.
void fft(vector<cd> &f, bool inv=false){
  int n = f.size(), mask = n - 1;
  vector<cd> tmp(n);
  for(int i = n >> 1; i >= 1; i >>= 1){
    cd zeta = polar(1., 2. * M_PI * i * (inv ? -1.: 1.) / n);
    cd w = 1;
    for(int j = 0; j < n; j += i){
      for(int k = 0; k < i; k++){
        tmp[j + k] = f[((j<<1)&mask) + k] + w * f[(((j<<1)+i)&mask)+k];
      }
      w *= zeta;
    }
    swap(f, tmp);
  }
}

void dft(vector<cd> &f){
  fft(f);
}

void idft(vector<cd> &f){
  fft(f, true);
  for(size_t i = 0; i < f.size(); i++)f[i] = f[i] / cd(f.size());
}

template <typename T>
vector<T> convolution(const vector<T> &f, const vector<T> &g){
  int n = 1;
  while(n < 2 * f.size() + 1)n *= 2;
  vector<cd> F(n, 0), G(n, 0);
  for(int i = 0; i < f.size(); i++)F[i] = cd(f[i]);
  for(int i = 0; i < g.size(); i++)G[i] = cd(g[i]);

  dft(F);
  dft(G);
  vector<cd> H(n);
  for(int i = 0; i < n; i++)H[i] = F[i] * G[i];
  idft(H);
  vector<T> h(n);
  for(int i = 0; i < n; i++){
    h[i] = T(round(H[i].real()));
  }
  return h;
}

vector<ll> convert_base(const vector<ll> &v, int old_b, int new_b){
  vector<ll> p(max(new_b, old_b) + 1);
  p[0] = 1;
  for(int i = 1; i < p.size(); i++)p[i] = p[i-1] * 10;
  vector<ll> res;
  ll curr = 0;
  int curr_b = 0;
  for(int i = 0; i < v.size(); i++){
    curr += v[i] * p[curr_b];
    curr_b += old_b;
    while(curr_b >= new_b){
      res.push_back(curr % p[new_b]);
      curr /= p[new_b];
      curr_b -= new_b;
    }
  }
  res.push_back(curr);
  while(!res.empty() && res.back() == 0)res.pop_back();
  return res;
}

vector<ll> simple_multiply(const vector<ll> &x, const vector<ll> &y){
  vector<ll> res(x.size() + y.size() - 1, 0);
  for(int i = 0; i < x.size(); i++){
    for(int j = 0; j < y.size(); j++){
      res[i+j] += x[i] * y[j];
    }
  }
  while(!res.empty() && res.back() == 0)res.pop_back();
  return res;
}

vector<ll> fft_multiply(const vector<ll> &x, const vector<ll> &y){
  int n = max(x.size(), y.size());
  vector<ll> a = x, b = y;
  a.resize(n, 0);
  b.resize(n, 0);
  vector<ll> conv = convolution<ll>(a, b);
  while(!conv.empty() && conv.back() == 0)conv.pop_back();
  return conv;
}

vector<ll> karatsuba_multiply(const vector<ll> &x, const vector<ll> &y){
  int n = max(x.size(), y.size());
  int m = 0;
  while((1 << m) < n)m++;
  n = (1 << m);
  vector<ll> a = x, b = y;
  a.resize(n, 0);
  b.resize(n, 0);
  if(n <= 32){
    return simple_multiply(a, b);
  }

  int k = n >> 1;
  vector<ll> a1(a.begin(), a.begin() + k);
  vector<ll> a2(a.begin() + k, a.end());
  vector<ll> b1(b.begin(), b.begin() + k);
  vector<ll> b2(b.begin() + k, b.end());

  vector<ll> a1b1 = karatsuba_multiply(a1, b1);
  vector<ll> a2b2 = karatsuba_multiply(a2, b2);
  for(int i = 0; i < k; i++)a2[i] += a1[i];
  for(int i = 0; i < k; i++)b2[i] += b1[i];
  vector<ll> z = karatsuba_multiply(a2, b2);
  for(int i = 0; i < a1b1.size(); i++)z[i] -= a1b1[i];
  for(int i = 0; i < a2b2.size(); i++)z[i] -= a2b2[i];

  vector<ll> res(2 * n, 0);
  for(int i = 0; i < a1b1.size(); i++)res[i] += a1b1[i];
  for(int i = 0; i < a2b2.size(); i++)res[i + n] += a2b2[i];
  for(int i = 0; i < z.size(); i++)res[i + k] += z[i];
  while(!res.empty() && res.back() == 0)res.pop_back();
  return res;
}

struct Bigint{
  const ll base = 100000000;
  const ll mbase = 1000; // 1000 for FFT, 10000 otherwise
  const int b = 8;
  const int mb = 3; // 3 for FFT, 10000 otherwise
  int sign = 1;
  vector<ll> dg;
  Bigint(){}
  Bigint(ll x){
    if(x < 0){
      sign = -1;
      x *= -1;
    }
    while(x){
      dg.push_back(x % base);
      x /= base;
    }
  }
  Bigint(const string &s){
    int e = 0;
    if(s[0] == '-'){
      sign = -1;
      e++;
    }
    for(int i = int(s.size()) - 1; i >= e; i-=b){
      int B = (i - b + 1 >= e ? b: i + 1 - e);
      ll x = stoll(s.substr(max(e, i - b + 1), B));
      dg.push_back(x);
    }
  }
  Bigint& operator=(const string &s){
    *this = Bigint(s);
    return *this;
  }
  Bigint& operator=(const Bigint &x){
    sign = x.sign;
    dg = x.dg;
    return *this;
  }
  Bigint& operator=(ll x){
    return (*this = Bigint(x));
  }
  Bigint operator-() const{
    Bigint res = *this;
    res.sign *= -1;
    return res;
  }
  Bigint operator+(const Bigint &x) const{
    if(sign == x.sign){
      Bigint res;
      res.sign = sign;
      res.dg.resize(max(dg.size(), x.dg.size()));
      ll carry = 0;
      for(int i = 0; i < max(dg.size(), x.dg.size()); i++){
        ll tmp = carry;
        if(i < dg.size())tmp += dg[i];
        if(i < x.dg.size())tmp += x.dg[i];
        res.dg[i] = (tmp % base);
        carry = tmp / base;
      }
      while(carry){
        res.dg.push_back(carry % base);
        carry /= base;
      }
      return res;
    }else{
      return (*this - (- x));
    }
  }
  void trim(){
    while(!dg.empty() && dg.back() == 0)dg.pop_back();
    if(dg.empty())sign = 1;
  }
  Bigint abs() const{
    Bigint res = *this;
    res.sign = 1;
    return res;
  }
  Bigint operator-(const Bigint &x) const{
    if(sign == x.sign){
      if(abs() >= x.abs()){
        Bigint res = *this;
        ll carry = 0;
        for(int i = 0; i < x.dg.size(); i++){
          res.dg[i] -= carry + x.dg[i];
          if(res.dg[i] < 0){
            res.dg[i] += base;
            carry = 1;
          }else{
            carry = 0;
          }
        }
        if(carry > 0){
          for(int i = x.dg.size(); i < res.dg.size() && carry > 0; i++){
            res.dg[i] -= carry;
            if(res.dg[i] < 0){
              res.dg[i] += base;
              carry = 1;
            }else{
              carry = 0;
            }
          }
        }
        res.trim();
        return res;
      }else{
        return - (x - *this);
      }
    }else{
      return (*this + (- x));
    }
  }
  bool operator<(const Bigint &x) const{
    if(sign != x.sign)return sign < x.sign;
    if(dg.size() != x.dg.size())return int(dg.size()) * sign < int(x.dg.size()) * x.sign;
    for(int i = int(dg.size()) - 1; i >= 0; i--){
      if(dg[i] != x.dg[i])return dg[i] * sign < x.dg[i] * x.sign;
    }
    return false;
  }
  bool operator>(const Bigint &x) const{
    return x < *this;
  }
  bool operator<=(const Bigint &x) const{
    return !(*this > x);
  }
  bool operator>=(const Bigint &x) const{
    return !(*this < x);
  }
  bool operator==(const Bigint &x) const{
    return !(*this < x) && !(x < *this);
  }
  bool operator!=(const Bigint &x) const{
    return (*this < x) || (x < *this);
  }
  friend istream& operator>>(istream &is, Bigint &x){
    string s;
    is >> s;
    x = s;
    return is;
  }
  friend ostream& operator<<(ostream& os, const Bigint &x){
    if(x.sign < 0)os << '-';
    if(x.dg.empty())os << 0;
    else{
      os << x.dg.back();
      for(int i = int(x.dg.size()) - 2; i >= 0; i--){
        os << setw(x.b) << setfill('0') << x.dg[i];
      }
    }
    return os;
  }
  Bigint& operator*=(ll x){
    if(x < 0){
      x *= -1;
      sign *= -1;
    }
    ll carry = 0;
    for(int i = 0; i < dg.size(); i++){
      carry = dg[i] * x + carry;
      dg[i] = carry % base;
      carry /= base;
    }
    while(carry){
      dg.push_back(carry % base);
      carry /= base;
    }
    trim();
    return *this;
  }
  Bigint operator*(ll x) const{
    Bigint res = *this;
    res *= x;
    return res;
  }
  Bigint operator*(const Bigint &v) const{
    vector<ll> x = convert_base(dg, b, mb);
    vector<ll> y = convert_base(v.dg, b, mb);

    if(x.empty())x.push_back(0);
    if(y.empty())y.push_back(0);
    // simple multiplication
    // vector<ll> mul = simple_multiply(x, y);
    // FFT
    vector<ll> mul = fft_multiply(x, y);
    // karatsuba
    // vector<ll> mul = karatsuba_multiply(x, y);

    Bigint res;
    res.sign = sign * v.sign;
    ll carry = 0;
    for(int i = 0; i < mul.size(); i++){
      carry += mul[i];
      res.dg.push_back(carry % mbase);
      carry /= mbase;
    }
    while(carry){
      res.dg.push_back(carry % mbase);
      carry /= mbase;
    }
    res.dg = convert_base(res.dg, mb, b);
    res.trim();
    return res;
  }
  // a = bq + r
  pair<Bigint, Bigint> divmod(const Bigint &a1, const Bigint &b1) const{
    ll norm = base / (b1.dg.back() + 1);
    Bigint q, r;
    q.sign = a1.sign * b1.sign;
    r.sign = a1.sign;

    Bigint a = a1.abs() * norm;
    Bigint b = b1.abs() * norm;
    q.dg.resize(a.dg.size());

    for(int i = int(a.dg.size()) - 1; i >= 0; i--){
      r = r * base + a.dg[i];
      ll s1 = (r.dg.size() <= b.dg.size() ? 0: r.dg[b.dg.size()]);
      ll s2 = (r.dg.size() <= int(b.dg.size()) - 1 ? 0: r.dg[int(b.dg.size()) - 1]);
      // temporary solution
      ll d = (base * s1 + s2) / b.dg.back();
      r -= b * d;
      // feedback
      while(r < 0)r += b, d--;
      q.dg[i] = d;
    }

    q.trim();
    r.trim();
    return make_pair(q, r / norm);
  }
  Bigint operator/(const Bigint &x) const{
    return divmod(*this, x).first;
  }
  Bigint operator%(const Bigint &x) const{
    return divmod(*this, x).second;
  }
  Bigint& operator/=(ll x){
    if(x < 0){
      x *= -1;
      sign *= -1;
    }
    ll rem = 0;
    for(int i = int(dg.size()) - 1; i >= 0; i--){
      rem = dg[i] + rem * base;
      dg[i] = rem / x;
      rem = rem % x;
    }
    trim();
    return *this;
  }
  Bigint operator/(ll x) const{
    Bigint res = *this;
    res /= x;
    return res;
  }
  Bigint operator%(ll x) const{
    if(x < 0)x *= -1;
    ll m = 0;
    for(int i = int(dg.size()) - 1; i >= 0; i--){
      m = (dg[i] + m * base) % x;
    }
    return m * sign;
  }
  Bigint& operator+=(const Bigint &x){
    *this = *this + x;
    return *this;
  }
  Bigint& operator-=(const Bigint &x){
    *this = *this - x;
    return *this;
  }
  Bigint& operator*=(const Bigint &x){
    *this = *this * x;
    return *this;
  }
  Bigint& operator/=(const Bigint &x){
    *this = *this / x;
    return *this;
  }
  bool iszero(){
    trim();
    if(dg.empty())return true;
    return false;
  }
  ll long_value() const {
    ll res = 0;
    for(int i = int(dg.size()) - 1; i >= 0; i--){
      res = res * base + dg[i];
    }
    return res * sign;
  }
};

Bigint fac[20010];

int main(int argc, char const* argv[])
{
  int n, m, r; cin >> n >> m >> r;
  if(n * m > r){
    cout << 0 << endl;
    return 0;
  }
  r -= n * m;
  fac[0] = Bigint(1);
  FOR(i, 1, 2001){
    fac[i] = Bigint(i) * fac[i-1];
  }
  Bigint res = fac[n + r - 1] / fac[r] / fac[n-1];
  cout << res << endl;
  return 0;
}
accuracy: 0.8
time_ms: 840
memory_kb: 9948
final_rank: 15

code_snippet: #include <bits/stdc++.h>

using namespace std;

const int BASE = 10000;

int n, m, r;

struct dat{
	vector <int> d;
	
	dat operator * (const int T) const{
		dat tmp;
		tmp.d = d;
		for(int i = 0; i < d.size(); i++)
		tmp.d[i] *= T;
		for(int i = 0; i < tmp.d.size(); i++){
			if(tmp.d[i] >= BASE){
				if(i == tmp.d.size() - 1)
				tmp.d.push_back(tmp.d[i] / BASE);
				else
				tmp.d[i + 1] += tmp.d[i] / BASE;
				tmp.d[i] %= BASE;
			}
		}
		return tmp;
	}
	
	dat operator / (const int T) const{
		dat tmp;
		tmp.d = d;
		int cur = 0;
		for(int i = tmp.d.size() - 1; i >= 0; i--){
			cur = cur * BASE + tmp.d[i];
			tmp.d[i] = cur / T;
			cur %= T;
		}
		
		for(int i = 0; i < tmp.d.size(); i++){
			if(tmp.d[i] >= BASE){
				if(i == tmp.d.size() - 1)
				tmp.d.push_back(tmp.d[i] / BASE);
				else
				tmp.d[i + 1] += tmp.d[i] / BASE;
				tmp.d[i] %= BASE;
			}
		}
		
		while(tmp.d.size() && tmp.d.back() == 0)
		tmp.d.pop_back();
		
		return tmp;
	}
	
	void print(){
		if(d.empty())
		printf("0");
		else{
			printf("%d", d.back());
			for(int i = d.size() - 2; i >= 0; i--){
				printf("%.4d", d[i]);
			}
		}
		printf("\n");
	}
}res;

int main(){
	scanf("%d%d%d", &n, &m, &r);
	
	r -= n * m;
	
	if(r < 0) return 0 * printf("0\n");
	
	//(n + r - 1)C(r)
	
	res.d.push_back(1);
	
	for(int i = 1; i <= n + r - 1; i++)
	res = res * i;
	
	for(int i = 1; i <= r; i++)
	res = res / i;
	
	for(int i = 1; i <= n - 1; i++)
	res = res / i;
	
	res.print();
	
}
accuracy: 1
time_ms: 2390
memory_kb: 3336
final_rank: 6

code_snippet: #include <bits/stdc++.h>

using namespace std;

const int BASE = 10000;

int n, m, r;

struct dat{
	vector <int> d;
	
	dat operator * (const int T) const{
		dat tmp;
		tmp.d = d;
		for(int i = 0; i < d.size(); i++)
		tmp.d[i] *= T;
		for(int i = 0; i < tmp.d.size(); i++){
			if(tmp.d[i] >= BASE){
				if(i == d.size() - 1)
				tmp.d.push_back(tmp.d[i] / BASE);
				else
				tmp.d[i + 1] += tmp.d[i] / BASE;
				tmp.d[i] %= BASE;
			}
		}
		return tmp;
	}
	
	dat operator / (const int T) const{
		dat tmp;
		tmp.d = d;
		
		int cur = 0;
		for(int i = tmp.d.size() - 1; i >= 0; i--){
			cur = cur * BASE + tmp.d[i];
			tmp.d[i] = cur / T;
			cur %= T;
		}
		
		while(tmp.d.size() && tmp.d.back() == 0)
		tmp.d.pop_back();
		
		return tmp;
	}
	
	void print(){
		if(d.empty())
		printf("0");
		else{
			printf("%d", d.back());
			for(int i = d.size() - 2; i >= 0; i--){
				printf("%.4d", d[i]);
			}
		}
		printf("\n");
	}
}res;

int main(){
	scanf("%d%d%d", &n, &m, &r);
	
	r -= n * m;
	
	if(r < 0) return 0 * printf("0\n");
	
	//(n + r - 1)C(r)
	
	res.d.reserve(10000);
	
	res.d.push_back(1);
	
	for(int i = 1; i <= n + r - 1; i++)
	res = res * i;
	
	for(int i = 1; i <= r; i++)
	res = res / i;
	
	for(int i = 1; i <= n - 1; i++)
	res = res / i;
	
	res.print();
	
}
accuracy: 0.8
time_ms: 2150
memory_kb: 3380
final_rank: 14

code_snippet: #include <stdio.h>
#include <vector>
#include <algorithm>
#include <bitset>
using namespace std;
#define PB push_back
const int N=2e4+10;
const long long int TOP=1e13;
struct bignum{
    int size;
    vector<long long int>val;
    void init(int n){
        val.clear();
        val.PB(n);
        pull();
        return ;
    }
    void pull(){
        int k=0;
        for(int i=0;i<val.size();i++){
            val[i]+=k;
            k=0;
            if(val[i]>=TOP){
                k=val[i]/TOP;
                val[i]%=TOP;
            }
        }
        if(k>0)val.PB(k);
        size=(int)val.size();
    }
    void out(){
        long long int now;
        reverse(val.begin(),val.end());
        printf("%lld",val[0]);
        for(int i=1;i<size;i++){
            now=TOP/10;
            while(val[i]<now){
                now/=10;
                printf("0");
            }
            printf("%lld",val[i]);
        }
        printf("\n");
        reverse(val.begin(),val.end());
        return ;
    }
    void operator *=(long long int n){
        for(int i=0;i<size;i++)val[i]*=n;
        pull();
        return ;
    }
};
void C(int a,int b){
    bignum ans;
    bitset<N> bs;
    vector<int> prime,mul;
    int temp;
    bs.reset();
    prime.PB(2);
    for(int i=3;i<N;i+=2)if(!bs[i]){
        prime.PB(i);
        for(int j=i*i;j<N;j+=(i<<1))bs[j]=true;
    }
    mul.resize(prime.size());
    for(int i=2;i<=a;i++){
        temp=i;
        for(int j=0;j<prime.size();j++){
            while(temp%prime[j]==0){
                mul[j]++;
                temp/=prime[j];
            }
            if(temp<=1)break;
        }
    }
    for(int i=2;i<=b;i++){
        temp=i;
        for(int j=0;j<prime.size();j++){
            while(temp%prime[j]==0){
                mul[j]--;
                temp/=prime[j];
            }
            if(temp<=1)break;
        }
    }
    for(int i=2;i<=a-b;i++){
        temp=i;
        for(int j=0;j<prime.size();j++){
            while(temp%prime[j]==0){
                mul[j]--;
                temp/=prime[j];
            }
            if(temp<=1)break;
        }
    }
    ans.init(1);
    for(int i=0;i<prime.size();i++){
        while(mul[i]>0){
            mul[i]--;
            ans*=prime[i];
        }
    }
    return ans.out();
}
void H(int a,int b){
    return C(a+b-1,b);
}
int main(){
    int n,m,r;
    scanf("%d%d%d",&n,&m,&r);
    if(n*m>r)printf("%d\n",0);
    else H(n,r-n*m);
}
accuracy: 1
time_ms: 20
memory_kb: 2840
final_rank: 1

code_snippet: #include <stdio.h>
#include <vector>
#include <algorithm>
#include <bitset>
using namespace std;
#define PB push_back
const int N=1e4+10;
const long long int TOP=1e13;
struct bignum{
    int size;
    vector<long long int>val;
    void init(int n){
        val.clear();
        val.PB(n);
        pull();
        return ;
    }
    void pull(){
        int k=0;
        for(int i=0;i<val.size();i++){
            val[i]+=k;
            k=0;
            if(val[i]>=TOP){
                k=val[i]/TOP;
                val[i]%=TOP;
            }
        }
        if(k>0)val.PB(k);
        size=(int)val.size();
    }
    void out(){
        long long int now;
        reverse(val.begin(),val.end());
        printf("%lld",val[0]);
        for(int i=1;i<size;i++){
            now=TOP/10;
            while(val[i]<now){
                now/=10;
                printf("0");
            }
            printf("%lld",val[i]);
        }
        printf("\n");
        reverse(val.begin(),val.end());
        return ;
    }
    void operator *=(long long int n){
        for(int i=0;i<size;i++)val[i]*=n;
        pull();
        return ;
    }
};
void C(int a,int b){
    bignum ans;
    bitset<N> bs;
    vector<int> prime,mul;
    int temp;
    bs.reset();
    prime.PB(2);
    for(int i=3;i<N;i+=2)if(!bs[i]){
        prime.PB(i);
        for(int j=i*i;j<N;j+=(i<<1))bs[j]=true;
    }
    mul.resize(prime.size());
    for(int i=2;i<=a;i++){
        temp=i;
        for(int j=0;j<prime.size();j++){
            while(temp%prime[j]==0){
                mul[j]++;
                temp/=prime[j];
            }
            if(temp<=1)break;
        }
    }
    for(int i=2;i<=b;i++){
        temp=i;
        for(int j=0;j<prime.size();j++){
            while(temp%prime[j]==0){
                mul[j]--;
                temp/=prime[j];
            }
            if(temp<=1)break;
        }
    }
    for(int i=2;i<=a-b;i++){
        temp=i;
        for(int j=0;j<prime.size();j++){
            while(temp%prime[j]==0){
                mul[j]--;
                temp/=prime[j];
            }
            if(temp<=1)break;
        }
    }
    ans.init(1);
    for(int i=0;i<prime.size();i++){
        while(mul[i]>0){
            mul[i]--;
            ans*=prime[i];
        }
    }
    return ans.out();
}
void H(int a,int b){
    return C(a+b-1,b);
}
int main(){
    int n,m,r;
    scanf("%d%d%d",&n,&m,&r);
    if(n*m>r)printf("%d\n",0);
    else H(n,r-n*m);
}
accuracy: 0.8
time_ms: 20
memory_kb: 2788
final_rank: 13

code_snippet: #include <stdio.h>
#include <vector>
#include <algorithm>
#include <bitset>
using namespace std;
#define PB push_back
const int N=1e4+10;
const long long int TOP=1e14;
struct bignum{
    int size;
    vector<long long int>val;
    void init(int n){
        val.clear();
        val.PB(n);
        pull();
        return ;
    }
    void pull(){
        int k=0;
        for(int i=0;i<val.size();i++){
            val[i]+=k;
            k=0;
            if(val[i]>=TOP){
                k=val[i]/TOP;
                val[i]%=TOP;
            }
        }
        if(k>0)val.PB(k);
        size=(int)val.size();
    }
    void out(){
        long long int now;
        reverse(val.begin(),val.end());
        printf("%lld",val[0]);
        for(int i=1;i<size;i++){
            now=TOP/10;
            while(val[i]<now){
                now/=10;
                printf("0");
            }
            printf("%lld",val[i]);
        }
        printf("\n");
        reverse(val.begin(),val.end());
        return ;
    }
    void operator *=(long long int n){
        for(int i=0;i<size;i++)val[i]*=n;
        pull();
        return ;
    }
};
void C(int a,int b){
    bignum ans;
    bitset<N> bs;
    vector<int> prime,mul;
    int temp;
    bs.reset();
    prime.PB(2);
    for(int i=3;i<N;i+=2)if(!bs[i]){
        prime.PB(i);
        for(int j=i*i;j<N;j+=(i<<1))bs[j]=true;
    }
    mul.resize(prime.size());
    for(int i=2;i<=a;i++){
        temp=i;
        for(int j=0;j<prime.size();j++){
            while(temp%prime[j]==0){
                mul[j]++;
                temp/=prime[j];
            }
            if(temp<=1)break;
        }
    }
    for(int i=2;i<=b;i++){
        temp=i;
        for(int j=0;j<prime.size();j++){
            while(temp%prime[j]==0){
                mul[j]--;
                temp/=prime[j];
            }
            if(temp<=1)break;
        }
    }
    for(int i=2;i<=a-b;i++){
        temp=i;
        for(int j=0;j<prime.size();j++){
            while(temp%prime[j]==0){
                mul[j]--;
                temp/=prime[j];
            }
            if(temp<=1)break;
        }
    }
    ans.init(1);
    for(int i=0;i<prime.size();i++){
        while(mul[i]>0){
            mul[i]--;
            ans*=prime[i];
        }
    }
    return ans.out();
}
void H(int a,int b){
    return C(a+b-1,b);
}
int main(){
    int n,m,r;
    scanf("%d%d%d",&n,&m,&r);
    if(n*m>r)printf("%d\n",0);
    else H(n,r-n*m);
}
accuracy: 0.8
time_ms: 10
memory_kb: 2756
final_rank: 12

code_snippet: #include <stdio.h>
const int N=2e3+10;
long long int ans[N][N];
long long int C(int a,int b){
    if(a==0)return 1;
    else if(b==0||b==a)return 1;
    if(ans[a][b]>0)return ans[a][b];
    else return ans[a][b]=C(a-1,b-1)+C(a-1,b);
}
long long int H(int a,int b){
    for(int i=0;i<=a;i++)for(int j=0;j<=b;j++)ans[i][j]=0;
    return C(a+b-1,b);
}
int main(){
    int n,m,r;
    scanf("%d%d%d",&n,&m,&r);
    if(n*m>r)printf("0\n");
    else printf("%lld\n",H(n,r-n*m));
}
accuracy: 0.6
time_ms: 290
memory_kb: 22460
final_rank: 19

code_snippet: #include <bits/stdc++.h>

using namespace std;
int n,m,r;

typedef long long ll;
class LINT{
    static const ll BASE =100000000LL;
    vector<ll> vl;
    bool sign;
    public:
    LINT(){sign=true;}
    LINT(ll x){
        if(x<0){
            sign=false;x*=-1;
        }
        else sign=true;
        while(x){
            vl.push_back(x%BASE);
            x/=BASE;
        }
    }
    LINT(string &x){
        sign = x[0]=='-'?false:true;
        ll dc=BASE;
        for(int i=x.size()-1;i>=0;--i){
            if(dc==BASE){
                vl.push_back(0);dc=1;
            }
            if(x[i]=='-') continue;
            else{
                vl.back() +=(x[i]-'0')*dc;
                dc*=10;
            }
        }
    }
    string getlint(){
        stringstream ss;
        if(!sign) ss<<'-';
        for(int i=vl.size()-1;i>=0;--i){
            ss<<vl[i];ss<<setw(8)<<setfill('0');
        }
        return ss.str();
    }
    LINT operator+(LINT &x){
        if(sign&&!x.sign){
            LINT t=x;
            t.sign=!t.sign;
            return *this-t;
        }
        else if(!sign&&x.sign){
            LINT t=*this;
            t.sign=!t.sign;
            return x-t;
            }
        LINT ret;
        ret.sign=sign;
        ll carry=0;int i=0;
        while(i<vl.size()||i<x.vl.size()||carry>0){
            if(i<vl.size()) carry +=vl[i];
            if(i<x.vl.size()) carry +=x.vl[i];
            ret.vl.push_back(carry%BASE);
            carry/=BASE;
            ++i;
        }
        return ret;
    }
    LINT operator-(LINT &x){
        if(!x.sign){
            LINT t=x;
            t.sign=!t.sign;
            return *this+t;
        }
        LINT ret;
        ll carry=0;int i=0;
        while(i<vl.size()||i<x.vl.size()){
            if(i<vl.size()) carry +=vl[i];
            if(i<x.vl.size()) carry -=x.vl[i];
            if(carry<0){
                ret.vl.push_back(carry+BASE);carry=-1;
            }
            else{
                ret.vl.push_back(carry);carry=0;
            }
            ++i;
        }
        if(carry==-1){
            ret.sign=!ret.sign;
            for(int j=0;j<ret.vl.size();++j) ret.vl[j]=BASE-ret.vl[j]-(j!=0);
        }
        while(ret.vl.size()>1&&ret.vl.back()==0) ret.vl.pop_back();
        return ret;
    }
    LINT operator*(LINT &x){
        LINT ret;
        if(vl.size()==0||x.vl.size()==0) return ret;
        ret.sign=!(sign^x.sign);
        ret.vl.assign(vl.size()+x.vl.size(),0);
        for(int i=0;i<vl.size();++i){
            for(int j=0;j<x.vl.size();++j){
                ret.vl[i+j] += vl[i]*x.vl[j];
                ret.vl[i+j+1] += ret.vl[i+j]/BASE;
                ret.vl[i+j] %=BASE;
            }
        }
        while(ret.vl.size()>0&&ret.vl.back()==0) ret.vl.pop_back();
        return ret;
    }
    LINT operator/(LINT &x){
        LINT ret,zero;
        if(vl.size()<x.vl.size()) return ret;
        LINT F(BASE/(x.vl[x.vl.size()-1]+1));
        LINT t=*this*F,tx=x*F;
        ret.vl.assign(t.vl.size()-tx.vl.size()+1,0);
        for(int i=ret.vl.size()-1,j=t.vl.size()-1;i>=0;--i,--j){
            ret.vl[i] =(j+1<t.vl.size()?t.vl[j+1]:0)*BASE+t.vl[j];
            ret.vl[i] /=tx.vl[tx.vl.size()-1];
            LINT tt;
            tt.vl.assign(i+tx.vl.size(),0);
            for(int k=0;k<tx.vl.size();++k) tt.vl[i+k]=ret.vl[i]*tx.vl[k];
            tt=tt+zero;
            while(t<tt){
                --ret.vl[i];
                for(int k=0;k<tx.vl.size();++k) tt.vl[i+k] -= tx.vl[k];
                tt=tt-zero;
            }
            t=t-tt;
        }
        ret=ret-zero;
        ret.sign=!(sign^x.sign);
        while(ret.vl.size()>0&&ret.vl.back()==0) ret.vl.pop_back();
        return ret;
        //return tt/F;
    }
    bool operator<(LINT &x){
        if(sign^x.sign) return x.sign;
        if(vl.size()!=x.vl.size()) return !(sign^(vl.size()<x.vl.size()));
        for(int i=vl.size()-1;i>=0;--i){
            if(vl[i]!=x.vl[i]) return !(sign^(vl[i]<x.vl[i]));
        }
        return false;
    }
};

string combination(int n,int k){
    if(n-k<k) k=n-k;
    vector<int> v(k);
    for(int i=0;i<k;++i) v[i]=n-i;
    for(int i=1;i<=k;++i){
        int t=i;
        for(int j=0;j<k;++j){
            int s=__gcd(t,v[j]);
            v[j] /=s;
            t /=s;
        }
    }
    LINT ret(1);
    for(int i=0;i<k;++i){
        LINT t=LINT(v[i]);
        ret = ret * t;   
    }
    return ret.getlint();
}

int main(){
    string ans;
    cin>>n>>m>>r;
    if(r<m*n) ans='0';
    else{
        r -=m*n;
        ans=combination(r+n-1,r);
    }
    cout<<ans<<endl;
    return 0;
}
accuracy: 1
time_ms: 1760
memory_kb: 3228
final_rank: 4

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i,n) REP(i,0,n)
#define REP(i,s,e) for(int i=(s); i<(int)(e); i++)
#define repr(i, n) REPR(i, n, 0)
#define REPR(i, s, e) for(int i=(int)(s-1); i>=(int)(e); i--)
#define pb push_back
#define all(r) r.begin(),r.end()
#define rall(r) r.rbegin(),r.rend()
#define fi first
#define se second

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int INF = 1e9;
const ll MOD = 1e9 + 7;
double EPS = 1e-8;

struct BigInteger {
	static const ll LogBase = 8;
	static const ll BASE = pow(10, LogBase);
	vector<ll> dig;
	bool isNeg;
	BigInteger() {}
	BigInteger(ll a, int sz, bool negative = false) : dig(sz, a), isNeg(negative) {}
	BigInteger(string s) {
		if (s[0] == '-') {
			isNeg = true;
			s = s.substr(1);
		} else isNeg = false;
		reverse(all(s));
		for (int i = 0; i < s.size(); i += LogBase) {
			dig.pb(0);
			ll p = 1;
			for (int j = 0; j < LogBase; j++) {
				if (i + j >= s.size()) break;
				dig.back() = dig.back() + (s[i + j] - '0') * p;
				p *= 10LL;
			}
		}
		while (size() > 1 && dig.back() == 0) dig.pop_back();
	}
	BigInteger(ll a) {
		isNeg = a < 0;
		dig.pb(abs(a));
		if(dig.back() >= BASE) {
			ll tmp = dig.back() / BASE;
			dig.back() %= BASE;
			dig.pb(tmp);
		}
		while (size() > 1 && dig.back() == 0) dig.pop_back();
	}
	int size() const {return dig.size();}
	BigInteger getAbs()const {
		if (!isNeg) return *this;
		BigInteger ret = *this;
		ret.isNeg = false;
		return ret.normal();
	}
	BigInteger normal() const {
		// BigInteger ret = this->getAbs();
		// for (int i = 0; i + 1 < ret.size(); ++i) {
		// 	if (ret.dig[i] >= BASE) ret.dig[i + 1] += ret.dig[i] / BASE, ret.dig[i] %= BASE;
		// }
		// if (ret.dig.back() >= BASE) {
		// 	ll tmp = ret.dig.back() / BASE;
		// 	ret.dig.back() %= BASE;
		// 	ret.dig.push_back(tmp);
		// }
		// while (ret.size() > 1 && ret.dig.back() == 0) ret.dig.pop_back();
		// return ret;
		BigInteger ret = *this;
		ret.normalize();
		return ret;
	}
	void normalize() {
		for(int i = 0; i +1 < size(); ++i) {
			if (dig[i] >= BASE) {
				dig[i+1] += dig[i] / BASE;
				dig[i] %= BASE;
			}
		}
		if(dig.back() >= BASE) {
			ll tmp = dig.back() / BASE;
			dig.back() %= BASE;
			dig.push_back(tmp);
		}
		while (size() > 1 && dig.back() == 0) dig.pop_back();
	}
	pair<BigInteger, ll> divMod(ll a) const {
		BigInteger x = *this;
		ll c = 0, t;
		for (int i = x.size() - 1; i >= 0; --i) {
			t = BASE * c + x.dig[i];
			x.dig[i] = t / a;
			c = t % a;
		}
		return pair<BigInteger, ll>(x.normal(), c);
	}
	pair<BigInteger, BigInteger> divMod(const BigInteger& bi) const {
		BigInteger x = this->getAbs(), y = bi.getAbs();
		if (x < y) return pair<BigInteger, BigInteger>(make_pair(BigInteger("0"), *this));
		if (x == y) return pair<BigInteger, BigInteger> (BigInteger("1"), BigInteger("0"));
		ll F = BASE / (y.dig.back() + 1);
		x = x * F;
		y = y * F;

		BigInteger z(0LL, x.size() - y.size() + 1, isNeg ^ bi.isNeg);
		for (int k = z.size() - 1, i = x.size() - 1; k >= 0; --k, --i) {
			z.dig[k] = (i + 1 < x.size() ? x.dig[i + 1] : 0) * BASE + x.dig[i];
			z.dig[k] /= y.dig.back();
			BigInteger t(0, k + y.size());
			for (int m = 0; m < y.size(); ++m) {
				t.dig[k + m] = z.dig[k] * y.dig[m];
			}

			t.normalize();
			while (x < t) {
				z.dig[k] -= 1;
				for (int m = 0; m < y.size(); ++m) {
					t.dig[k + m] -= y.dig[m];
				}
				t.normalize();
			}
			x = x - t;
		}
		return pair<BigInteger, BigInteger>(z.normal(), x / F);
	}
	BigInteger operator + (const BigInteger& bi) const {
		bool retNeg = false;
		if (isNeg) {
			if (bi.isNeg) retNeg = true;
			else return bi - (this->getAbs());
		}
		if (bi.isNeg) return (*this) - bi.getAbs();
		BigInteger ret (0LL, max(this->size(), bi.size()) + 1, retNeg);
		for (int i = 0; i + 1 < ret.size(); ++i) {
			if (i < this->size()) ret.dig[i] += this->dig[i];
			if (i < bi.size()) ret.dig[i] += bi.dig[i];
			if (ret.dig[i] >= BASE) ret.dig[i] -= BASE, ++ret.dig[i + 1];
		}
		return ret.normal();
	}
	BigInteger operator - (const BigInteger& bi) const {
		if (bi.isNeg) return (*this) + bi.getAbs();
		if (isNeg) return bi - (this -> getAbs());
		if ((*this) < bi) {
			BigInteger ret = bi - (*this);
			ret.isNeg = true;
			return ret;
		}
		BigInteger ret = *this;
		for (int i = 0; i < bi.size(); ++i) {
			ret.dig[i] -= bi.dig[i];
			if (ret.dig[i] < 0) ret.dig[i] += BASE, --ret.dig[i+1];
		}
		return ret.normal();
	}
	BigInteger operator * (const ll a) const {
		BigInteger ret = *this;
		for (auto& d : ret.dig) d *= a;
		return ret.normal();
	}
	BigInteger operator * (const BigInteger& bi)  const {
		BigInteger ret(0LL, this->size() + bi.size(), isNeg ^ bi.isNeg);
		for (int i = this->size()-1; i >= 0; --i) {
			for (int j = 0; j < bi.size(); ++j) {
				ret.dig[i + j] += this->dig[i] * bi.dig[j];
			}
			ret.normalize();
		}
		return ret.normal();
	}
	BigInteger operator / (ll a) const {return this->divMod(a).first;}
	ll operator % (ll a) const {return this->divMod(a).second;}
	BigInteger operator / (const BigInteger& bi) const {return this->divMod(bi).first;}
	BigInteger operator % (const BigInteger& bi) const {return this->divMod(bi).second;}
	bool operator < (const BigInteger& bi) const {
		if (this->size() != bi.size()) return this->size() < bi.size();
		for (int i = this->size() - 1; i >= 0; --i) {
			if (dig[i] != bi.dig[i]) return dig[i] < bi.dig[i];
		}
		return false;
	}
	bool operator > (const BigInteger& bi) const {return bi < (*this);}
	bool operator <= (const BigInteger& bi) const {!(*this > bi);}
	bool operator >= (const BigInteger& bi) const {!(*this < bi);}
	bool operator != (const BigInteger& bi) const {(*this < bi) || (*this > bi);}
	bool operator == (const BigInteger& bi) const {!(*this != bi);}
	void print() const{
		if(isNeg) printf("-");
		printf("%lld", dig.back());
		for(int i = size()-2; i>=0; --i) printf("%0*lld", LogBase, dig[i]);
	}
	void println() const {
		print();
		puts("");
	}
};
ostream &operator << (ostream &os, const BigInteger& x) {
	if (x.isNeg) os << '-';
	os << x.dig[x.size() - 1];
	for (int i = x.size() - 2; i >= 0; --i) {
		os << setw(BigInteger::LogBase) << setfill('0') << x.dig[i];
	}
	return os;
}
istream &operator >> (istream &is, BigInteger &x) {
	string s; is >> s; x = BigInteger(s); return is;
}


int main() {
	ll n, m, r;
	cin >> n >> m >> r;
	BigInteger b = BigInteger("1");
	int R = r - n * m;
	if(R < 0) {
		cout << 0 << endl;
		return 0;
	}
	for(int i = 0; i < n-1; ++i) {
		if((R+n-1-i) % (i+1) == 0) {
			b = b * BigInteger((R+n-1-i) / (i+1));
		}
		else {
			b = b * BigInteger(R+n-1-i) / BigInteger(i+1);
		}
	}
	cout << b << endl;
	return 0;
}
accuracy: 1
time_ms: 7030
memory_kb: 3236
final_rank: 9

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i,n) REP(i,0,n)
#define REP(i,s,e) for(int i=(s); i<(int)(e); i++)
#define repr(i, n) REPR(i, n, 0)
#define REPR(i, s, e) for(int i=(int)(s-1); i>=(int)(e); i--)
#define pb push_back
#define all(r) r.begin(),r.end()
#define rall(r) r.rbegin(),r.rend()
#define fi first
#define se second

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int INF = 1e9;
const ll MOD = 1e9 + 7;
double EPS = 1e-8;

struct BigInteger {
	static const ll LogBase = 8;
	static const ll BASE = pow(10, LogBase);
	vector<ll> dig;
	bool isNeg;
	BigInteger() {}
	BigInteger(ll a, int sz, bool negative = false) : dig(sz, a), isNeg(negative) {}
	BigInteger(string s) {
		if (s[0] == '-') {
			isNeg = true;
			s = s.substr(1);
		} else isNeg = false;
		reverse(all(s));
		for (int i = 0; i < s.size(); i += LogBase) {
			dig.pb(0);
			ll p = 1;
			for (int j = 0; j < LogBase; j++) {
				if (i + j >= s.size()) break;
				dig.back() = dig.back() + (s[i + j] - '0') * p;
				p *= 10LL;
			}
		}
		while (size() > 1 && dig.back() == 0) dig.pop_back();
	}
	BigInteger(ll a) {
		isNeg = a < 0;
		dig.pb(abs(a));
		if(dig.back() >= BASE) {
			ll tmp = dig.back() / BASE;
			dig.back() %= BASE;
			dig.pb(tmp);
		}
		while (size() > 1 && dig.back() == 0) dig.pop_back();
	}
	int size() const {return dig.size();}
	BigInteger getAbs()const {
		if (!isNeg) return *this;
		BigInteger ret = *this;
		ret.isNeg = false;
		return ret.normal();
	}
	BigInteger normal() const {
		BigInteger ret = this->getAbs();
		for (int i = 0; i + 1 < ret.size(); ++i) {
			while (ret.dig[i] >= BASE) ret.dig[i + 1] += ret.dig[i] / BASE, ret.dig[i] %= BASE;
		}
		if (ret.dig.back() >= BASE) {
			ll tmp = ret.dig.back() / BASE;
			ret.dig.back() %= BASE;
			ret.dig.push_back(tmp);
		}
		while (ret.size() > 1 && ret.dig.back() == 0) ret.dig.pop_back();
		return ret;
	}
	pair<BigInteger, ll> divMod(ll a) const {
		BigInteger x = *this;
		ll c = 0, t;
		for (int i = x.size() - 1; i >= 0; --i) {
			t = BASE * c + x.dig[i];
			x.dig[i] = t / a;
			c = t % a;
		}
		return pair<BigInteger, ll>(x.normal(), c);
	}
	pair<BigInteger, BigInteger> divMod(const BigInteger& bi) const {
		BigInteger x = this->getAbs(), y = bi.getAbs();
		if (x < y) return pair<BigInteger, BigInteger>(make_pair(BigInteger("0"), *this));
		if (x == y) return pair<BigInteger, BigInteger> (BigInteger("1"), BigInteger("0"));
		ll F = BASE / (y.dig.back() + 1);
		x = x * F;
		y = y * F;

		BigInteger z(0LL, x.size() - y.size() + 1, isNeg ^ bi.isNeg);
		for (int k = z.size() - 1, i = x.size() - 1; k >= 0; --k, --i) {
			z.dig[k] = (i + 1 < x.size() ? x.dig[i + 1] : 0) * BASE + x.dig[i];
			z.dig[k] /= y.dig.back();
			BigInteger t(0, k + y.size());
			for (int m = 0; m < y.size(); ++m) {
				t.dig[k + m] = z.dig[k] * y.dig[m];
			}

			t = t.normal();
			while (x < t) {
				z.dig[k] -= 1;
				for (int m = 0; m < y.size(); ++m) {
					t.dig[k + m] -= y.dig[m];
				}
				t = t.normal();
			}
			x = x - t;
		}
		return pair<BigInteger, BigInteger>(z.normal(), x / F);
	}
	BigInteger operator + (const BigInteger& bi) const {
		bool retNeg = false;
		if (isNeg) {
			if (bi.isNeg) retNeg = true;
			else bi - (this->getAbs());
		}
		if (bi.isNeg) return (*this) - bi.getAbs();
		BigInteger ret (0LL, max(this->size(), bi.size()) + 1, retNeg);
		for (int i = 0; i + 1 < ret.size(); ++i) {
			if (i < this->size()) ret.dig[i] += this->dig[i];
			if (i < bi.size()) ret.dig[i] += bi.dig[i];
			if (ret.dig[i] >= BASE) ret.dig[i] -= BASE, ++ret.dig[i + 1];
		}
		return ret.normal();
	}
	BigInteger operator - (const BigInteger& bi) const {
		if (bi.isNeg) return (*this) + bi.getAbs();
		if (isNeg) return bi - (this -> getAbs());
		if ((*this) < bi) {
			BigInteger ret = bi - (*this);
			ret.isNeg = true;
			return ret;
		}
		BigInteger ret = *this;
		for (int i = 0; i < bi.size(); ++i) {
			ret.dig[i] -= bi.dig[i];
			if (ret.dig[i] < 0) ret.dig[i] += BASE, --ret.dig[i+1];
		}
		return ret.normal();
	}
	BigInteger operator * (const ll a) const {
		BigInteger ret = *this;
		for (auto& d : ret.dig) d *= a;
		return ret.normal();
	}
	BigInteger operator * (const BigInteger& bi)  const {
		BigInteger ret(0LL, this->size() + bi.size(), isNeg ^ bi.isNeg);
		for (int i = 0; i < this->size(); ++i) {
			for (int j = 0; j < bi.size(); ++j) {
				ret.dig[i + j] += this->dig[i] * bi.dig[j];
			}
			for(int j = 0; j + 1< ret.size(); ++j) {
				if(ret.dig[j] >= BASE) {
					ret.dig[j+1] += ret.dig[j] / BASE;
					ret.dig[j] %= BASE;
				}
			}
			if(ret.dig.back() >= BASE) {
				ll tmp = ret.dig.back() / BASE;
				ret.dig.back() %= BASE;
				ret.dig.push_back(tmp);
			}
		}
		return ret.normal();
	}
	BigInteger operator / (ll a) const {return this->divMod(a).first;}
	ll operator % (ll a) const {return this->divMod(a).second;}
	BigInteger operator / (const BigInteger& bi) const {return this->divMod(bi).first;}
	BigInteger operator % (const BigInteger& bi) const {return this->divMod(bi).second;}
	bool operator < (const BigInteger& bi) const {
		if (this->size() != bi.size()) return this->size() < bi.size();
		for (int i = this->size() - 1; i >= 0; --i) {
			if (dig[i] != bi.dig[i]) return dig[i] < bi.dig[i];
		}
		return false;
	}
	bool operator > (const BigInteger& bi) const {return bi < (*this);}
	bool operator <= (const BigInteger& bi) const {!(*this > bi);}
	bool operator >= (const BigInteger& bi) const {!(*this < bi);}
	bool operator != (const BigInteger& bi) const {(*this < bi) || (*this > bi);}
	bool operator == (const BigInteger& bi) const {!(*this != bi);}
	void print() const{
		if(isNeg) printf("-");
		printf("%lld", dig.back());
		for(int i = size()-2; i>=0; --i) printf("%0*lld", LogBase, dig[i]);
	}
	void println() const {
		print();
		puts("");
	}
};
ostream &operator << (ostream &os, const BigInteger& x) {
	if (x.isNeg) os << '-';
	os << x.dig[x.size() - 1];
	for (int i = x.size() - 2; i >= 0; --i) {
		os << setw(BigInteger::LogBase) << setfill('0') << x.dig[i];
	}
	return os;
}
istream &operator >> (istream &is, BigInteger &x) {
	string s; is >> s; x = BigInteger(s); return is;
}


int main() {
	ll n, m, r;
	cin >> n >> m >> r;
	BigInteger b = BigInteger("1");
	int R = r - n * m;
	if(R < 0) {
		cout << 0 << endl;
		return 0;
	}
	for(int i = 0; i < n-1; ++i) {
		b = b * BigInteger(R+n-1-i);
		b = b /BigInteger(i+1);
	}
	cout << b << endl;
	return 0;
}
accuracy: 1
time_ms: 7620
memory_kb: 3248
final_rank: 10

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i,n) REP(i,0,n)
#define REP(i,s,e) for(int i=(s); i<(int)(e); i++)
#define repr(i, n) REPR(i, n, 0)
#define REPR(i, s, e) for(int i=(int)(s-1); i>=(int)(e); i--)
#define pb push_back
#define all(r) r.begin(),r.end()
#define rall(r) r.rbegin(),r.rend()
#define fi first
#define se second

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int INF = 1e9;
const ll MOD = 1e9 + 7;
double EPS = 1e-8;

struct BigInteger {
	static const ll LogBase = 8;
	static const ll BASE = pow(10, LogBase);
	vector<ll> dig;
	bool isNeg;
	BigInteger() {}
	BigInteger(ll a, int sz, bool negative = false) : dig(sz, a), isNeg(negative) {}
	BigInteger(string s) {
		if (s[0] == '-') {
			isNeg = true;
			s = s.substr(1);
		} else isNeg = false;
		reverse(all(s));
		for (int i = 0; i < s.size(); i += LogBase) {
			dig.pb(0);
			ll p = 1;
			for (int j = 0; j < LogBase; j++) {
				if (i + j >= s.size()) break;
				dig.back() = dig.back() + (s[i + j] - '0') * p;
				p *= 10LL;
			}
		}
		while (size() > 1 && dig.back() == 0) dig.pop_back();
	}
	BigInteger(ll a) {
		isNeg = a < 0;
		dig.pb(abs(a));
		if(dig.back() >= BASE) {
			ll tmp = dig.back() / BASE;
			dig.back() %= BASE;
			dig.pb(tmp);
		}
		while (size() > 1 && dig.back() == 0) dig.pop_back();
	}
	int size() const {return dig.size();}
	BigInteger getAbs()const {
		if (!isNeg) return *this;
		BigInteger ret = *this;
		ret.isNeg = false;
		return ret;
	}
	BigInteger normal() const {
		BigInteger ret = this->getAbs();
		for (int i = 0; i + 1 < ret.size(); ++i) {
			while (ret.dig[i] >= BASE) ret.dig[i + 1] += ret.dig[i] / BASE, ret.dig[i] %= BASE;
		}
		if (ret.dig.back() >= BASE) {
			ll tmp = ret.dig.back() / BASE;
			ret.dig.back() %= BASE;
			ret.dig.push_back(tmp);
		}
		while (ret.size() > 1 && ret.dig.back() == 0) ret.dig.pop_back();
		return ret;
	}
	pair<BigInteger, ll> divMod(ll a) const {
		BigInteger x = *this;
		ll c = 0, t;
		for (int i = x.size() - 1; i >= 0; --i) {
			t = BASE * c + x.dig[i];
			x.dig[i] = t / a;
			c = t % a;
		}
		return pair<BigInteger, ll>(x.normal(), c);
	}
	pair<BigInteger, BigInteger> divMod(const BigInteger& bi) const {
		BigInteger x = this->getAbs(), y = bi.getAbs();
		if (x < y) return pair<BigInteger, BigInteger>(make_pair(BigInteger("0"), *this));
		if (x == y) return pair<BigInteger, BigInteger> (BigInteger("1"), BigInteger("0"));
		ll F = BASE / (y.dig.back() + 1);
		x = x * F;
		y = y * F;

		BigInteger z(0LL, x.size() - y.size() + 1, isNeg ^ bi.isNeg);
		for (int k = z.size() - 1, i = x.size() - 1; k >= 0; --k, --i) {
			z.dig[k] = (i + 1 < x.size() ? x.dig[i + 1] : 0) * BASE + x.dig[i];
			z.dig[k] /= y.dig.back();
			BigInteger t(0, k + y.size());
			for (int m = 0; m < y.size(); ++m) {
				t.dig[k + m] = z.dig[k] * y.dig[m];
			}

			t = t.normal();
			while (x < t) {
				z.dig[k] -= 1;
				for (int m = 0; m < y.size(); ++m) {
					t.dig[k + m] -= y.dig[m];
				}
				t = t.normal();
			}
			x = x - t;
		}
		return pair<BigInteger, BigInteger>(z.normal(), x / F);
	}
	BigInteger operator + (const BigInteger& bi) const {
		bool retNeg = false;
		if (isNeg) {
			if (bi.isNeg) retNeg = true;
			else bi - (this->getAbs());
		}
		if (bi.isNeg) return (*this) - bi.getAbs();
		BigInteger ret (0LL, max(this->size(), bi.size()) + 1, retNeg);
		for (int i = 0; i + 1 < ret.size(); ++i) {
			if (i < this->size()) ret.dig[i] += this->dig[i];
			if (i < bi.size()) ret.dig[i] += bi.dig[i];
			if (ret.dig[i] >= BASE) ret.dig[i] -= BASE, ++ret.dig[i + 1];
		}
		if (ret.dig.back() == 0LL) ret.dig.pop_back();
		return ret;
	}
	BigInteger operator - (const BigInteger& bi) const {
		if (bi.isNeg) return (*this) + bi.getAbs();
		if (isNeg) return bi - (this -> getAbs());
		if ((*this) < bi) {
			BigInteger ret = bi - (*this);
			ret.isNeg = true;
			return ret;
		}
		BigInteger ret = *this;
		for (int i = 0; i < bi.size(); ++i) {
			ret.dig[i] -= bi.dig[i];
			if (dig[i] < 0) ret.dig[i] += BASE, --ret.dig[i];
		}
		return ret;
	}
	BigInteger operator * (const ll a) const {
		BigInteger ret = *this;
		for (auto& d : ret.dig) d *= a;
		return ret.normal();
	}
	BigInteger operator * (const BigInteger& bi)  const {
		BigInteger ret(0LL, this->size() + bi.size(), isNeg ^ bi.isNeg);
		for (int i = 0; i < this->size(); ++i) {
			for (int j = 0; j < bi.size(); ++j) {
				ret.dig[i + j] += this->dig[i] * bi.dig[j];
			}
		}
		return ret.normal();
	}
	BigInteger operator / (ll a) const {return this->divMod(a).first;}
	ll operator % (ll a) const {return this->divMod(a).second;}
	BigInteger operator / (const BigInteger& bi) const {return this->divMod(bi).first;}
	BigInteger operator % (const BigInteger& bi) const {return this->divMod(bi).second;}
	bool operator < (const BigInteger& bi) const {
		if (this->size() != bi.size()) return this->size() < bi.size();
		for (int i = this->size() - 1; i >= 0; --i) {
			if (dig[i] != bi.dig[i]) return dig[i] < bi.dig[i];
		}
		return false;
	}
	bool operator > (const BigInteger& bi) const {return bi < (*this);}
	bool operator <= (const BigInteger& bi) const {!(*this > bi);}
	bool operator >= (const BigInteger& bi) const {!(*this < bi);}
	bool operator != (const BigInteger& bi) const {(*this < bi) || (*this > bi);}
	bool operator == (const BigInteger& bi) const {!(*this != bi);}
	void print() const{
		if(isNeg) printf("-");
		printf("%lld", dig.back());
		for(int i = size()-2; i>=0; --i) printf("%0*lld", LogBase, dig[i]);
	}
	void println() const {
		print();
		puts("");
	}
};
ostream &operator << (ostream &os, const BigInteger& x) {
	if (x.isNeg) os << '-';
	os << x.dig[x.size() - 1];
	for (int i = x.size() - 2; i >= 0; --i) {
		os << setw(BigInteger::LogBase) << setfill('0') << x.dig[i];
	}
	return os;
}
istream &operator >> (istream &is, BigInteger &x) {
	string s; is >> s; x = BigInteger(s); return is;
}


int main() {
	ll n, m, r;
	cin >> n >> m >> r;
	BigInteger b = BigInteger("1");
	int R = r - n * m;
	if(R < 0) {
		cout << 0 << endl;
		return 0;
	}
	for(int i = 0; i < n-1; ++i) {
		b = b * BigInteger(R+n-1-i);
		b = b /BigInteger(i+1);
	}
	cout << b << endl;

	return 0;
}
accuracy: 0.6
time_ms: 20
memory_kb: 3188
final_rank: 16

code_snippet: #include <bits/stdc++.h>
  
using namespace std;
  
#define rep(i,n) REP(i,0,n)
#define REP(i,s,e) for(int i=(s); i<(int)(e); i++)
#define repr(i, n) REPR(i, n, 0)
#define REPR(i, s, e) for(int i=(int)(s-1); i>=(int)(e); i--)
#define pb push_back
#define all(r) r.begin(),r.end()
#define rall(r) r.rbegin(),r.rend()
#define fi first
#define se second
  
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
 
const int INF = 1e9;
const ll MOD = 1e9 + 7;
double EPS = 1e-8;

const int MAX_N=200010;

ll gcd(ll a, ll b){
    return b == 0LL ? a : gcd(b, a%b);
}
ll lcm(ll a, ll b){
    return a / gcd(a, b) * b;
}
ll extgcd(ll a, ll b, ll &x, ll &y){
    ll g = a;
    x = 1LL;
    y = 0LL;
    if(b != 0) g = extgcd(b, a%b, y, x), y-= (a/b)*x;
    return g;
}
ll fact[MAX_N], ifact[MAX_N];
ll mod_inverse(int a){
    ll x, y;
    extgcd(a, MOD, x, y);
    return(MOD+x%MOD)%MOD;
}

void makeFact(){
    fact[0]=ifact[0] = 1LL;
    for(int i = 1; i < MAX_N; i++){
        fact[i] = fact[i-1]*i%MOD;
        ifact[i] = mod_inverse(fact[i]);
    }
}

ll c(int n, int r){
    if(n < 0 || r < 0 || r > n) return 0;
    if(r > n / 2) r = n-r;
    return fact[n]*ifact[n-r]%MOD*ifact[r]%MOD;
}

int main(){
	makeFact();
	int n, m, r;
	cin >> n >> m >> r;
	int R = r - m*n;
	if(R < 0) {
		cout << 0 << endl;
		return 0;
	}
	cout << c(R+n-1, R) << endl;
	return 0;
}
accuracy: 0.6
time_ms: 50
memory_kb: 6212
final_rank: 17

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<cstdio>
#include<sstream>
#include<iomanip>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define mp make_pair
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
using namespace std;
//kaewasuretyuui
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef pair<int,pii> pip;
typedef vector<pip>vip	;
const double PI=acos(-1);
const double EPS=1e-8;
const int inf=1<<30;
class Calc{
	#define N 1000
	#define MOD 100000000
    public:
    ll carry, borrow,w,remainder;
	ll z[N];
	void ladd(ll a[], ll b[]){
		carry=0;
		for(int i=N-1;i>=0;i--){
			z[i]=a[i]+b[i]+carry;
			if(z[i]<MOD)carry=0;
			else{
				z[i]-=MOD;
				carry=1;
			}
		}
	}
	void lsub(ll a[], ll b[]){
		borrow=0;
		for(int i=N-1;i>=0;i--){
			z[i]=a[i]-b[i]-borrow;
			if(z[i]>=0)borrow=0;
			else{
				z[i]+=MOD;
				borrow=1;
			}
		}
	}
	void lmul(ll c[], ll d){
		carry=0;
		for(int i=N-1;i>=0;i--){
			w=c[i];
			z[i]=(w*d+carry)%MOD;
			carry=(w*d+carry)/MOD;
		}
	}
	void ldiv(ll c[],ll d){
		remainder=0;
		for(int i=0;i<N;i++){
			w=c[i];
			z[i]=(w+remainder)/d;
			remainder=((w+remainder)%d)*MOD;
		}
	}
	void displayL(ll s[]){
		int t=0;
		for(;t<N;t++)if(s[t]){
			printf("%d",s[t]);
			break;
		}
		for(t++;t<N;t++)printf("%08d",s[t]);
		printf("\n");
	}
	void displayS(ll s){
		for(int i=0;i<N-1;i++)printf("%8s"," ");
		printf("%08d\n",s);
	}
};
int main(){
	Calc calc;
	ll a,b,c;
	cin>>a>>b>>c;
	c-=a*b;
	if(c<0){
		cout<<0<<endl;
	}else{
		rep(i,N){
			calc.z[i]=0;
		}
		calc.z[N-1]=1;
		loop(i,1,c+a)calc.lmul(calc.z,i);
		loop(i,1,c+1)calc.ldiv(calc.z,i);
		loop(i,1,a)calc.ldiv(calc.z,i);
		calc.displayL(calc.z);
	}
}
accuracy: 0.8
time_ms: 270
memory_kb: 1172
final_rank: 11

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<cstdio>
#include<sstream>
#include<iomanip>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define mp make_pair
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
using namespace std;
//kaewasuretyuui
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef pair<int,pii> pip;
typedef vector<pip>vip	;
const double PI=acos(-1);
const double EPS=1e-8;
const int inf=1<<30;
class Calc{
	#define N 10000
	#define MOD 100000000
    public:
    ll carry, borrow,w,remainder;
	ll z[N];
	void ladd(ll a[], ll b[]){
		carry=0;
		for(int i=N-1;i>=0;i--){
			z[i]=a[i]+b[i]+carry;
			if(z[i]<MOD)carry=0;
			else{
				z[i]-=MOD;
				carry=1;
			}
		}
	}
	void lsub(ll a[], ll b[]){
		borrow=0;
		for(int i=N-1;i>=0;i--){
			z[i]=a[i]-b[i]-borrow;
			if(z[i]>=0)borrow=0;
			else{
				z[i]+=MOD;
				borrow=1;
			}
		}
	}
	void lmul(ll c[], ll d){
		carry=0;
		for(int i=N-1;i>=0;i--){
			w=c[i];
			z[i]=(w*d+carry)%MOD;
			carry=(w*d+carry)/MOD;
		}
	}
	void ldiv(ll c[],ll d){
		remainder=0;
		for(int i=0;i<N;i++){
			w=c[i];
			z[i]=(w+remainder)/d;
			remainder=((w+remainder)%d)*MOD;
		}
	}
	void displayL(ll s[]){
		int t=0;
		for(;t<N;t++)if(s[t]){
			printf("%d",s[t]);
			break;
		}
		for(t++;t<N;t++)printf("%08d",s[t]);
		printf("\n");
	}
	void displayS(ll s){
		for(int i=0;i<N-1;i++)printf("%8s"," ");
		printf("%08d\n",s);
	}
};
int main(){
	Calc calc;
	ll a,b,c;
	cin>>a>>b>>c;
	c-=a*b;
	if(c<0){
		cout<<0<<endl;
	}else{
		rep(i,N){
			calc.z[i]=0;
		}
		calc.z[N-1]=1;
		loop(i,1,c+a)calc.lmul(calc.z,i);
		loop(i,1,c+1)calc.ldiv(calc.z,i);
		loop(i,1,a)calc.ldiv(calc.z,i);
		calc.displayL(calc.z);
	}
}
accuracy: 1
time_ms: 2840
memory_kb: 1244
final_rank: 5

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<cstdio>
#include<sstream>
#include<iomanip>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define mp make_pair
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
using namespace std;
//kaewasuretyuui
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef pair<int,pii> pip;
typedef vector<pip>vip	;
const double PI=acos(-1);
const double EPS=1e-8;
const int inf=1<<30;
class Calc{
	#define N 10000
	#define MOD 100000000
    public:
    int carry, borrow,w,remainder;
	int z[N];
	void ladd(int a[], int b[]){
		carry=0;
		for(int i=N-1;i>=0;i--){
			z[i]=a[i]+b[i]+carry;
			if(z[i]<MOD)carry=0;
			else{
				z[i]-=MOD;
				carry=1;
			}
		}
	}
	void lsub(int a[], int b[]){
		borrow=0;
		for(int i=N-1;i>=0;i--){
			z[i]=a[i]-b[i]-borrow;
			if(z[i]>=0)borrow=0;
			else{
				z[i]+=MOD;
				borrow=1;
			}
		}
	}
	void lmul(int c[], int d){
		carry=0;
		for(int i=N-1;i>=0;i--){
			w=c[i];
			z[i]=(w*d+carry)%MOD;
			carry=(w*d+carry)/MOD;
		}
	}
	void ldiv(int c[], int d){
		remainder=0;
		for(int i=0;i<N;i++){
			w=c[i];
			z[i]=(w+remainder)/d;
			remainder=((w+remainder)%d)*MOD;
		}
	}
	void displayL(int s[]){
		int t=0;
		for(;t<N;t++)if(s[t]){
			printf("%d",s[t]);
			break;
		}
		for(t++;t<N;t++)printf("%08d",s[t]);
		printf("\n");
	}
	void displayS(int s){
		for(int i=0;i<N-1;i++)printf("%8s"," ");
		printf("%08d\n",s);
	}
};
int main(){
	Calc calc;
	ll a,b,c;
	cin>>a>>b>>c;
	c-=a*b;
	if(c<0){
		cout<<0<<endl;
	}else{
		rep(i,N){
			calc.z[i]=0;
		}
		calc.z[N-1]=1;
		loop(i,1,c+a)calc.lmul(calc.z,i);
		loop(i,1,c+1)calc.ldiv(calc.z,i);
		loop(i,1,a)calc.ldiv(calc.z,i);
		calc.displayL(calc.z);
	}
}
accuracy: 0.4
time_ms: 10
memory_kb: 1184
final_rank: 20

code_snippet: //??????2???1??¨???1???2???????????????1???2??¨???2???1?????°??????????????¨???????????????
//a[0] + ??? + a[n-1] = r - mn (a[i] >= 0)????????????a[0]???a[n]????????¶???????????° ??? ??????
//????????????[r - mn + n - 1]C[n-1]????????¨?????´??????0<=m<=n<=r<=10000????????§?????????????????????
//????????????(r-mn+n-1)!/(n-1)!/(r-mn)!????????????DivTa baityou.
#include <iostream>
#include <cstdio>
using namespace std;

class BigInt{
public:
	int d[30000];	//1000?????°??§?????£?????????(??????????°???????????????????)
	int n;			//?????§?????°
	
	BigInt(int n){
		this->n = n;
		for( int i = 0; i < n; i++ ) d[i] = 0;
		d[0] = 1;
	}
	void mult(int x){
		for( int i = 0; i < n; i++ ){
			d[i] *= x;
		}
		for( int i = 0; i < n; i++ ){
			d[i+1] += (d[i] / 1000);
			d[i] %= 1000;
		}
	}
	void div(int x){
		for( int i = n-1; i >= 0; i-- ){
			if( i > 0 )
				d[i-1] += (d[i] % x) * 1000;
			d[i] /= x;
		}
	}
	void output(int p, bool isPut0=true){
		if( isPut0 )
			printf("%03d", d[p]);
		else
			printf("%d", d[p]);
	}
	void disp(int r){
		for( int i = r-1; i >= 0; i-- )
			printf("%d", d[i]);
		puts("");
	}
};
BigInt big(29000);

int main()
{
	int n, m, r;
	int i;
	
	cin >> n >> m >> r;
	if( r - m*n < n ){ cout << 0 << endl; return 0; }
	
	for( i = r - m*n + n - 1; i >= n; i-- )
		big.mult(i);
	for( i = 1; i <= r - m*n; i++ )
		big.div(i);
	
	i = 28999;
	while( big.d[i] == 0 ){ i--; }
	big.output(i--, false);
	while( i >= 0 ){
		big.output(i);
		i--;
	}
	cout << endl;
	return 0;
}
accuracy: 1
time_ms: 3570
memory_kb: 1312
final_rank: 7