Cod sursa(job #2397908)

Utilizator cella.florescuCella Florescu cella.florescu Data 4 aprilie 2019 21:17:44
Problema Pedefe Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.7 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXV = 500;
const int MAXN = 500;
const int MOD = 666013;

int aib[MAXN + 1][MAXV + 1], dp[2][MAXN + 1][MAXN + 1];
short s[3][MAXN + 1], len[3];

inline short zero(short x) {
  return x & -x;
}

inline void update(int wh[], short pos, int val) {
  for (pos = pos; pos <= MAXV; pos += zero(pos)) {
    wh[pos] += val;
    if (wh[pos] >= MOD)
      wh[pos] -= MOD;
  }
}

inline int query(int wh[], short pos) {
  int ans = 0;
  for (pos = pos; pos > 0; pos -= zero(pos)) {
    ans += wh[pos];
    if (ans >= MOD)
      ans -= MOD;
  }
  return ans;
}

int main()
{
    ifstream fin("pedefe.in");
    fin >> len[0] >> len[1] >> len[2];
    for (short ind = 0; ind < 3; ++ind)
      for (short i = 1; i <= len[ind]; ++i)
        fin >> s[ind][i];
    fin.close();
    dp[0][0][0] = s[0][0] = s[1][0] = 1;
    for (short k = 0, ind = 0; k <= len[2]; ++k, ind = 1 - ind) {
      memset(aib, 0, sizeof aib);
      memset(dp[1 - ind], 0, sizeof dp[1 - ind]);
      for (short i = 0; i <= len[0]; ++i) {
        int upd = 0;
        for (short j = 0; j <= len[1]; ++j) {
          upd += dp[ind][i][j];
          if (upd >= MOD)
            upd -= MOD;
          update(aib[j], s[0][i], upd);
          if (i < len[0] && j < len[1] && s[0][i + 1] == s[1][j + 1]) {
            int pos = (ind ^ (s[2][k + 1] == s[0][i + 1]));
            dp[pos][i + 1][j + 1] += query(aib[j], s[0][i + 1]);
            if (dp[pos][i + 1][j + 1] >= MOD)
              dp[pos][i + 1][j + 1] -= MOD;
          }
        }
      }
    }
    ofstream fout("pedefe.out");
    fout << query(aib[len[1]], MAXV) << '\n';
    fout.close();
    return 0;
}