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

#include <cstdio>
#include <cstring>
#include <iostream>
#define REP(i, n) for (int i = 0; i < (int)(n); i++)

using namespace std;

long long nCk[64][64];

int buff[64];

long long solve2(int n, long long m, int k) {
  // printf("solve2(%d,%lld,%d): ", n, m, k);puts("");

  if (m == 0) {
    // printf("%d %d\\n", n, k);
    for (int i = 0; i < k; i++)
      buff[i] = 1;
    throw 0;
  }

  if (n == 0)
    return 1;

  if (m >= nCk[n][k])
    return nCk[n][k];

  long long cnt = 0;

  for (int i = 0; i <= 1; i++) {
    if (n == k && i == 0)
      continue;
    // printf("buff[%d] => %d\\n", n - 1, i);
    buff[n - 1] = i;
    cnt += solve2(n - 1, m - cnt, k - i);
  }

  return cnt;
}

void solve(int n, long long m) { REP(i, n + 1) m -= solve2(n, m, i); }

int main() {
  for (int i = 0; i < 64; i++) {
    nCk[i][i] = nCk[i][0] = 1;
    for (int j = 1; j < i; j++)
      nCk[i][j] = nCk[i - 1][j - 1] + nCk[i - 1][j];
  }
  // REP(i,5){ REP(j,i+1) printf("%lld ", nCk[i][j]); puts(""); }

  while (true) {
    int n;
    long long m;
    cin >> n >> m;

    if (n + m == 0)
      break;

    try {
      solve(n, m - 1);
    } catch (int e) {
    }

    for (int i = n - 1; i >= 0; i--)
      printf("%d", buff[i]);
    puts("");

    memset(buff, 0, sizeof(buff));
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define f first
#define s second
#define mp make_pair

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define rep(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define ALL(c) (c).begin(), (c).end()
#define IN(x, s, g) ((x) >= (s) && (x) < (g))
#define ISIN(x, y, w, h) (IN((x), 0, (w)) && IN((y), 0, (h)))
#define print(x) printf("%d\\n", x)

using namespace std;

typedef unsigned long long ull;

const int _dx[] = {0, 1, 0, -1};
const int _dy[] = {-1, 0, 1, 0};

int getInt() {
  int ret = 0, c;
  c = getchar();
  while (!isdigit(c))
    c = getchar();
  while (isdigit(c)) {
    ret *= 10;
    ret += c - '0';
    c = getchar();
  }
  return ret;
}

int gcd(int a, int b) {
  if (a > b)
    swap(a, b);
  if (a == 0)
    return b;
  return gcd(a, b % a);
}

ull nCk(int n, int k) {
  int ue[k];
  int si[k];
  ull ret = 1;

  REP(i, k) {
    ue[i] = n - i;
    si[i] = i + 1;
  }

  REP(i, k) REP(j, k) {
    int tmp = gcd(ue[i], si[j]);
    if (tmp != 1) {
      ue[i] /= tmp;
      si[j] /= tmp;
    }
  }

  REP(i, k) ret *= (ull)ue[i];

  return ret;
}

ull solve2(int n, int m, int z) {
  // printf("solve2(%d, %d, %d)\\n", n, m, z);
  if (n == 1)
    return (z + 1) % 2;
  if (m == 0)
    return (((ull)1) << (n - z)) - 1;

  // ¶[É½ÂÌ0ª±­©
  ull all = 0;

  for (int i = z; i >= 0; i--) {
    ull tmp = nCk(n - i, z - i);
    // printf("all = %lld, %dC%d = %lld\\n", all, n-i, z-i, tmp);
    if (all + tmp <= m)
      all += tmp;
    else
      return (((ull)1) << (n - i - 1)) + solve2(n - i - 1, m - all, z - i);
  }

  return (((ull)1) << (n - 1)) + solve2(n - 1, m - all, z);
}

ull solve(int n, int m) {
  ull all = 0;
  int i = n;

  while (true) {
    ull tmp = nCk(n, i);
    if (all + tmp <= m)
      all += tmp;
    else
      break;
    i--;
  }

  return solve2(n, m - all, i);
}

void printll(ull val, int n) {
  if (n == 0)
    return;
  printll(val >> 1, n - 1);
  printf("%d", (int)(val & 1));
}

int main() {
  while (true) {
    int n = getInt();
    int m = getInt() - 1;

    if (n + m == -1)
      break;

    printll(solve(n, m), n);
    puts("");
  }
  return 0;
}