Dang_Quan_10_Tin

NLCS

Aug 26th, 2022 (edited)
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.36 KB | None | 0 0
  1. #define task "NLCS"
  2. #include <iostream>
  3. #include <cstdio>
  4. #include <algorithm>
  5. #include <vector>
  6.  
  7. using namespace std;
  8.  
  9. using ll = long long;
  10. using ld = long double;
  11.  
  12. constexpr int N = 1e4 + 5;
  13. constexpr int mod = 123456789;
  14. int m, n;
  15. int a[N], b[N], dp[N], f[N], lcs[N], LCS[N];
  16. vector<int> s;
  17. vector<int> pos[N * 2];
  18.  
  19. void Read()
  20. {
  21.     cin >> m >> n;
  22.  
  23.     for (int i = 1; i <= m; ++i)
  24.     {
  25.         cin >> a[i];
  26.         s.emplace_back(a[i]);
  27.     }
  28.  
  29.     for (int i = 1; i <= n; ++i)
  30.     {
  31.         cin >> b[i];
  32.         s.emplace_back(b[i]);
  33.     }
  34. }
  35.  
  36. #define Find(x, v) (lower_bound(x.begin(), x.end(), v) - x.begin() + 1)
  37. void Compress()
  38. {
  39.     sort(s.begin(), s.end());
  40.     s.resize(unique(s.begin(), s.end()) - s.begin());
  41.  
  42.     for (int i = 1; i <= m; ++i)
  43.         a[i] = Find(s, a[i]);
  44.     for (int i = 1; i <= n; ++i)
  45.         b[i] = Find(s, b[i]);
  46. }
  47.  
  48. void Solve()
  49. {
  50.     for (int i = 1; i <= n; ++i)
  51.         pos[b[i]].emplace_back(i);
  52.  
  53.     dp[0] = 1;
  54.  
  55.     for (int i = 1; i <= m; ++i)
  56.     {
  57.         int ans(0), res(0);
  58.  
  59.         for (int j = 0; j <= n; ++j)
  60.         {
  61.             if (a[i] == b[j])
  62.             {
  63.                 lcs[j] = ans;
  64.                 f[j] = res;
  65.             }
  66.             else
  67.             {
  68.                 lcs[j] = LCS[j];
  69.                 f[j] = dp[j];
  70.             }
  71.  
  72.             if (LCS[j] + 1 > ans)
  73.             {
  74.                 ans = LCS[j] + 1;
  75.                 res = dp[j];
  76.             }
  77.             else if (LCS[j] + 1 == ans)
  78.                 (res += dp[j]) %= mod;
  79.         }
  80.  
  81.         for (int j = (int)pos[a[i]].size() - 1; j > 0; --j)
  82.             if (lcs[pos[a[i]][j]] == lcs[pos[a[i]][j - 1]])
  83.                 (f[pos[a[i]][j]] -= f[pos[a[i]][j - 1]]) %= mod;
  84.         // cerr << "ok\n";
  85.  
  86.         swap(f, dp);
  87.         swap(lcs, LCS);
  88.     }
  89.  
  90.     int ans(0), res(0);
  91.  
  92.     for (int i = 0; i <= n; ++i)
  93.         if (LCS[i] > ans)
  94.         {
  95.             ans = LCS[i];
  96.             res = dp[i];
  97.         }
  98.         else if (LCS[i] == ans)
  99.             (res += dp[i]) %= mod;
  100.  
  101.     cout << ans << " " << (res + mod) % mod;
  102. }
  103.  
  104. int32_t main()
  105. {
  106.     ios_base::sync_with_stdio(0);
  107.     cin.tie(0);
  108.     cout.tie(0);
  109.  
  110.     if (fopen(task ".INP", "r"))
  111.     {
  112.         freopen(task ".INP", "r", stdin);
  113.         freopen(task ".OUT", "w", stdout);
  114.     }
  115.  
  116.     Read();
  117.     Compress();
  118.     Solve();
  119. }
Advertisement
Add Comment
Please, Sign In to add comment