Problem p04042 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

#define mp make_pair
#define ff first
#define ss second
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(v) v.begin(), v.end()

const int maxn = 2e3 + 100, maxk = 1e4 + 10, base = 1380;
const ll inf = 2e18, mod = 1e9 + 7;

int n, k, sz[maxn], hashVal[maxn];
char s[maxn][maxk], ans[maxk];
set<int> st;
pair<int, int> pool[2][maxn];
bitset<maxk> dp[maxn];

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);

  cin >> n >> k;
  for (int i = 0; i < n; i++) {
    cin >> s[i], sz[i] = strlen(s[i]);
    ll HASH = 0;
    for (int j = 0; j < sz[i]; j++)
      HASH = (HASH * base + s[i][j]) % mod;
    hashVal[i] = HASH;
  }

  dp[n][0] = true;
  for (int i = n - 1; i >= 0; i--)
    dp[i] = (dp[i + 1] | (dp[i + 1] << sz[i]));

  int now = 0, tail = 0;
  for (int i = 0; i < n; i++) {
    if (dp[i + 1][k - sz[i]] && st.find(hashVal[i]) == st.end())
      pool[now][tail++] = mp(i, 0);
    st.insert(hashVal[i]);
  }

  for (int len = 0; len < k; len++) {
    char c = 'z';
    for (int i = 0; i < tail; i++)
      c = min(c, s[pool[now][i].ff][pool[now][i].ss]);

    /*cerr << "HERE " << len << ' ' << c << ':' << tail << endl;
    for (int i = 0; i < tail; i++)
            cerr << pool[now][i].ff << ' ' << pool[now][i].ss << endl;*/

    int TAIL = 0, mnpos = mod, x, y;
    for (int i = 0; i < tail; i++) {
      x = pool[now][i].ff;
      y = pool[now][i].ss;
      if (s[x][y] == c) {
        if (y + 1 == sz[x]) {
          mnpos = min(mnpos, x);
          // cerr << "###" << endl;
        } else {
          pool[now ^ 1][TAIL++] = mp(x, y + 1);
          // cerr << "$$$" << endl;
        }
      }
    }
    st.clear();
    if (mnpos != mod)
      for (int i = mnpos + 1; i < n; i++) {
        // cerr << "DEBUG " << mnpos << ' ' << i << endl;
        if ((k - len - 1 - sz[i] >= 0 && dp[i + 1][k - len - 1 - sz[i]]) &&
            st.find(hashVal[i]) == st.end())
          pool[now ^ 1][TAIL++] = mp(i, 0);
        st.insert(hashVal[i]);
      }

    tail = TAIL;
    now ^= 1;
    ans[len] = c;
  }

  cout << ans << endl;
}


Fixed submission:
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

#define mp make_pair
#define ff first
#define ss second
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(v) v.begin(), v.end()

const int maxn = 2e3 + 100, maxk = 1e4 + 10, base = 1380;
const ll inf = 2e18, mod = 1e9 + 7;

int n, k, sz[maxn], hashVal[maxn];
char s[maxn][maxk], ans[maxk];
set<int> st;
pair<int, int> pool[2][maxn * maxk];
bitset<maxk> dp[maxn];

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);

  cin >> n >> k;
  for (int i = 0; i < n; i++) {
    cin >> s[i], sz[i] = strlen(s[i]);
    ll HASH = 0;
    for (int j = 0; j < sz[i]; j++)
      HASH = (HASH * base + s[i][j]) % mod;
    hashVal[i] = HASH;
  }

  dp[n][0] = true;
  for (int i = n - 1; i >= 0; i--)
    dp[i] = (dp[i + 1] | (dp[i + 1] << sz[i]));

  int now = 0, tail = 0;
  for (int i = 0; i < n; i++) {
    if (dp[i + 1][k - sz[i]] && st.find(hashVal[i]) == st.end())
      pool[now][tail++] = mp(i, 0);
    st.insert(hashVal[i]);
  }

  for (int len = 0; len < k; len++) {
    char c = 'z';
    for (int i = 0; i < tail; i++)
      c = min(c, s[pool[now][i].ff][pool[now][i].ss]);

    /*cerr << "HERE " << len << ' ' << c << ':' << tail << endl;
    for (int i = 0; i < tail; i++)
            cerr << pool[now][i].ff << ' ' << pool[now][i].ss << endl;*/

    int TAIL = 0, mnpos = mod, x, y;
    for (int i = 0; i < tail; i++) {
      x = pool[now][i].ff;
      y = pool[now][i].ss;
      if (s[x][y] == c) {
        if (y + 1 == sz[x]) {
          mnpos = min(mnpos, x);
          // cerr << "###" << endl;
        } else {
          pool[now ^ 1][TAIL++] = mp(x, y + 1);
          // cerr << "$$$" << endl;
        }
      }
    }
    st.clear();
    if (mnpos != mod)
      for (int i = mnpos + 1; i < n; i++) {
        // cerr << "DEBUG " << mnpos << ' ' << i << endl;
        if ((k - len - 1 - sz[i] >= 0 && dp[i + 1][k - len - 1 - sz[i]]) &&
            st.find(hashVal[i]) == st.end())
          pool[now ^ 1][TAIL++] = mp(i, 0);
        st.insert(hashVal[i]);
      }

    tail = TAIL;
    now ^= 1;
    ans[len] = c;
  }

  cout << ans << endl;
}