Problem p02109 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define NUM 22

int POW[NUM + 1], RANK[4194304], max_union[4194304], num[4194304];
vector<int> STATE[NUM + 1];
set<int> SET[4194304];

void calc() {

  int count;

  for (int state = 0; state < POW[NUM]; state++) {
    count = 0;
    for (int loop = 0; loop < NUM; loop++) {
      if (state & (1 << loop)) {
        count++;
      }
    }
    RANK[state] = count;
    STATE[count].push_back(state);
  }
}

int main() {

  for (int i = 0; i < NUM + 1; i++)
    POW[i] = pow(2, i);
  for (int i = 0; i < POW[NUM]; i++) {
    num[i] = 0;
    max_union[i] = i;
  }

  calc();

  int N;
  scanf("%d", &N);

  int k, tmp, sum;
  for (int loop = 0; loop < N; loop++) {
    scanf("%d", &k);
    sum = 0;
    for (int i = 0; i < k; i++) {
      scanf("%d", &tmp);
      tmp--;
      sum += POW[tmp];
    }
    num[sum]++;
    SET[sum].insert(sum);
  }

  int current_state, plus_one_bit_state;
  int ans = 0, copy_count;

  for (int num_bit = NUM; num_bit >= 1; num_bit--) {
    for (int k = 0; k < STATE[num_bit].size(); k++) {
      current_state = STATE[num_bit][k];

      for (int add_bit = 0; add_bit < NUM; add_bit++) {
        if (current_state & (1 << add_bit))
          continue;

        plus_one_bit_state = current_state + POW[add_bit];

        if (SET[plus_one_bit_state].size() > 0) {

          set<int>::iterator it = SET[plus_one_bit_state].begin();
          copy_count = 0;
          while (copy_count < 3 && it != SET[plus_one_bit_state].end()) {
            SET[current_state].insert(*it);
            it++;
            copy_count++;
          }
          max_union[current_state] |= max_union[plus_one_bit_state];
        }
      }

      if ((SET[current_state].size() >= 3) ||
          (num[current_state] > 0 &&
           num[current_state] + SET[current_state].size() - 1 >= 3)) {
        ans = max(ans, RANK[max_union[current_state]] * RANK[current_state]);
      }
    }
  }

  printf("%d\n", ans);

  return 0;
}


Fixed submission:
#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define NUM 22

int POW[NUM + 1], RANK[4194304], max_union[4194304], num[4194304];
vector<int> STATE[NUM + 1];
set<int> SET[4194304];

void calc() {

  int count;

  for (int state = 0; state < POW[NUM]; state++) {
    count = 0;
    for (int loop = 0; loop < NUM; loop++) {
      if (state & (1 << loop)) {
        count++;
      }
    }
    RANK[state] = count;
    STATE[count].push_back(state);
  }
}

int main() {

  for (int i = 0; i < NUM + 1; i++)
    POW[i] = pow(2, i);
  for (int i = 0; i < POW[NUM]; i++) {
    num[i] = 0;
    max_union[i] = i;
  }

  calc();

  int N;
  scanf("%d", &N);

  int k, tmp, sum;
  for (int loop = 0; loop < N; loop++) {
    scanf("%d", &k);
    sum = 0;
    for (int i = 0; i < k; i++) {
      scanf("%d", &tmp);
      tmp--;
      sum += POW[tmp];
    }
    num[sum]++;
    SET[sum].insert(sum);
  }

  int current_state, plus_one_bit_state;
  int ans = 0, copy_count;

  for (int num_bit = NUM; num_bit >= 1; num_bit--) {
    for (int k = 0; k < STATE[num_bit].size(); k++) {
      current_state = STATE[num_bit][k];

      for (int add_bit = 0; add_bit < NUM; add_bit++) {
        if (current_state & (1 << add_bit))
          continue;

        plus_one_bit_state = current_state + POW[add_bit];

        if (SET[plus_one_bit_state].size() > 0) {

          set<int>::iterator it = SET[plus_one_bit_state].begin();
          copy_count = 0;
          while (SET[current_state].size() + copy_count < 3 &&
                 it != SET[plus_one_bit_state].end()) {
            SET[current_state].insert(*it);
            it++;
            copy_count++;
          }
          max_union[current_state] |= max_union[plus_one_bit_state];
        }
      }

      if ((SET[current_state].size() >= 3) ||
          (num[current_state] > 0 &&
           num[current_state] + SET[current_state].size() - 1 >= 3)) {
        ans = max(ans, RANK[max_union[current_state]] * RANK[current_state]);
      }
    }
  }

  printf("%d\n", ans);

  return 0;
}