Problem p01261 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <iostream>
#include <string>
#include <vector>
using namespace std;

typedef unsigned long long ull;

ull nCr(ull n, ull r) {
  if (r == 0)
    return 1;

  bool used[r + 1];
  ull res = 1;
  fill(used, used + r + 1, false);
  for (ull i = n, i2 = 0; i2 < r; i--, i2++) {
    res *= i;
    for (ull j = 1; j <= r; j++) {
      if (used[j])
        continue;
      if (res % j == 0) {
        res /= j, used[j] = true;
      }
    }
  }
  return res;
}

ull d[64];

int countBit(ull n) {
  int ret = 0;
  for (int i = 60; i > 0; i--) {
    if (n >= d[i]) {
      ret++;
      n -= d[i];
    }
  }
  return ret;
}

string toBit(ull n, int m) {
  string ret = "";
  for (int i = m; i > 0; i--) {
    if (n >= d[i]) {
      ret += '1';
      n -= d[i];
    } else
      ret += '0';
  }
  return ret;
}

ull getValue(ull a, ull N) {
  ull value = 0;
  for (ull i = 0; i < N; i++)
    if ((1ull << i) & a)
      value += (1ull << i);
  return value;
}

int main() {
  ull N, M;

  for (int i = 0; i < 64; i++)
    d[i] = 1;
  for (int i = 2; i < 64; i++)
    d[i] = d[i - 1] * 2;

  while (cin >> N >> M, N | M) {

    if (M == 1) {
      cout << toBit(0, N) << endl;
      continue;
    }

    vector<ull> v;
    for (int i = 0; i <= N; i++) {
      if (i == 0)
        v.push_back(nCr(N, i));
      else
        v.push_back(nCr(N, i) + v[i - 1]);
    }

    int bit = 0;
    ull cnt = 0;
    for (int i = 0; i <= N; i++) {
      if (v[i] >= M) {
        bit = i;
        cnt = v[i - 1];
        break;
      }
    }
    //    cout << "bit = " << bit << " cnt = " << cnt << endl;

    ull value = 0;
    for (ull i = 0; i < bit; i++)
      value += (1ull << i);

    //    cout << "value = " << value << endl;
    cnt++;

    int C = 0;
    while (true) {
      //      C++;
      //      if(C == 20)break;
      for (ull i = N; i >= 0; i--) {
        if (cnt == M)
          goto end;
        if (!(value & (1ull << i)))
          continue;
        //	cout << "i = " << i << endl;
        //	cout << "value = " << value << endl;
        ull n = i, c = countBit(getValue(value, i));
        //	cout << "value = " << value << endl;
        //	cout << "value2 = " << value-(1<<i) << endl;
        //	cout << "n = " << n << " c = " << c << endl;
        //	cout << "nCr = " << nCr(n,c) << endl;
        if (cnt + nCr(n, c) <= M) {
          cnt += nCr(n, c);
          value -= (1ull << i);
          value += (1ull << (i + 1));
          //	  cout << "enter" << endl;
          break;
        }
      }
    }

  end:
    cout << toBit(value, N) << endl;
    //    cout << "C = " << C << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

typedef unsigned long long ull;

ull nCr(ull n, ull r) {
  if (r == 0)
    return 1;

  bool used[r + 1];
  ull res = 1;
  fill(used, used + r + 1, false);
  for (int i = n, i2 = 0; i2 < r; i--, i2++) {
    res *= i;
    for (int j = 1; j <= r; j++) {
      if (used[j])
        continue;
      if (res % j == 0) {
        res /= j, used[j] = true;
      }
    }
  }
  return res;
}

ull d[64];

int countBit(ull n) {
  int ret = 0;
  for (int i = 60; i > 0; i--) {
    if (n >= d[i]) {
      ret++;
      n -= d[i];
    }
  }
  return ret;
}

string toBit(ull n, int m) {
  string ret = "";
  for (int i = m; i > 0; i--) {
    if (n >= d[i]) {
      ret += '1';
      n -= d[i];
    } else
      ret += '0';
  }
  return ret;
}

ull getValue(ull a, ull N) {
  ull value = 0;
  for (int i = 0; i < N; i++)
    if ((1 << i) & a)
      value += (1 << i);
  return value;
}

int main() {
  ull N, M;

  for (int i = 0; i < 64; i++)
    d[i] = 1;
  for (int i = 2; i < 64; i++)
    d[i] = d[i - 1] * 2;

  while (cin >> N >> M, N | M) {

    if (M == 1) {
      cout << toBit(0, N) << endl;
      continue;
    }

    vector<ull> v;
    for (int i = 0; i <= N; i++) {
      if (i == 0)
        v.push_back(nCr(N, i));
      else
        v.push_back(nCr(N, i) + v[i - 1]);
    }

    int bit = 0;
    ull cnt = 0;
    for (int i = 0; i <= N; i++) {
      if (v[i] >= M) {
        bit = i;
        cnt = v[i - 1];
        break;
      }
    }
    //    cout << "bit = " << bit << " cnt = " << cnt << endl;

    ull value = 0;
    for (int i = 0; i < bit; i++)
      value += (1 << i);

    //    cout << "value = " << value << endl;
    cnt++;

    int C = 0;
    while (true) {
      //      C++;
      //      if(C == 20)break;
      for (int i = N; i >= 0; i--) {
        if (cnt == M)
          goto end;
        if (!(value & (1 << i)))
          continue;
        ///	cout << "i = " << i << endl;
        ull n = i, c = countBit(getValue(value, i));
        //	cout << "value = " << value << endl;
        //	cout << "value2 = " << value-(1<<i) << endl;
        //	cout << "n = " << n << " c = " << c << endl;
        //	cout << "nCr = " << nCr(n,c) << endl;
        if (cnt + nCr(n, c) <= M) {
          cnt += nCr(n, c);
          value -= (1 << i);
          value += (1 << (i + 1));
          //	  cout << "enter" << endl;
          break;
        }
      }
    }

  end:
    cout << toBit(value, N) << endl;
    //    cout << "C = " << C << endl;
  }
  return 0;
}