Advertisement
Josif_tepe

Untitled

Aug 4th, 2023
867
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.73 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cstring>
  4. #include <vector>
  5. #include <set>
  6. #include <map>
  7. #include <stack>
  8. using namespace std;
  9. typedef long long ll;
  10. const int maxn = 1e5 + 10;
  11. const int INF = 2e9;
  12. int n;
  13. int a[maxn], b[maxn];
  14. int L[maxn], R[maxn];
  15. int segment_tree[4 * maxn];
  16. void solve_subtask2() {
  17.     int x = b[0];
  18.     int res = 0;
  19.     for(int i = 0; i < n; i++) {
  20.         if(a[i] == x) {
  21.             res++;
  22.             int j = i - 1;
  23.             while(j >= 0 and a[j] <= x) {
  24.                 j--;
  25.                 res++;
  26.             }
  27.             j = i + 1;
  28.             while(j < n and a[j] <= x) {
  29.                 res++;
  30.                 j++;
  31.             }
  32.             i = j - 1;
  33.         }
  34.     }
  35.     cout << res << endl;
  36. }
  37. int dp[5005][5005];
  38. int rec(int i, int j) {
  39.     if(i < 0 or j < 0) {
  40.         return 0;
  41.     }
  42.     if(dp[i][j] != -1) {
  43.         return dp[i][j];
  44.     }
  45.     int res = 0;
  46.     if(a[i] == b[j] and L[i] < j and R[i] > j) {
  47.         res = max(res, rec(i, j - 1) + 1);
  48.     }
  49.     res = max(res, rec(i - 1, j));
  50.     res = max(res, rec(i, j - 1));
  51.     return dp[i][j] = res;
  52. }
  53. void build_tree(int L, int R, int node) {
  54.     if(L == R) {
  55.         segment_tree[node] = 0;
  56.         return;
  57.     }
  58.     int middle = (L + R) / 2;
  59.     build_tree(L, middle, 2 * node);
  60.     build_tree(middle + 1, R, 2 * node + 1);
  61.     segment_tree[node] = max(segment_tree[2 * node], segment_tree[2 * node + 1]);
  62. }
  63. int query(int i, int j, int L, int R, int node) {
  64.     // L  R i L R j L R
  65.     if(i <= L and R <= j) {
  66.         return segment_tree[node];
  67.     }
  68.     if(R < i or j < L) {
  69.         return 0;
  70.     }
  71.     int middle = (L + R) / 2;
  72.     return max(query(i, j, L, middle, 2 * node), query(i, j, middle + 1, R, 2 * node + 1));
  73. }
  74. void update(int idx, int new_value, int L, int R, int node) {
  75.     if(L == R) {
  76.         segment_tree[node] = new_value;
  77.         return;
  78.     }
  79.     int middle = (L + R) / 2;
  80.     if(idx <= middle) {
  81.         update(idx, new_value, L, middle, 2 * node);
  82.     }
  83.     else {
  84.         update(idx, new_value, middle + 1, R, 2 * node + 1);
  85.     }
  86.     segment_tree[node] = max(segment_tree[2 * node], segment_tree[2 * node + 1]);
  87. }
  88. int main() {
  89.     ios_base::sync_with_stdio(false);
  90.     cin >> n;
  91.     set<int> st;
  92.     vector<int> t(n + 5);
  93.     for(int i = 0; i < n; i++) {
  94.         cin >> a[i];
  95.         t[i + 1] = a[i];
  96.     }
  97.     for(int i = 0; i < n; i++) {
  98.         cin >> b[i];
  99.         st.insert(b[i]);
  100.     }
  101.     t[0] = INF;
  102.     t[n + 1] = INF;
  103.     stack<int> s;
  104.     s.push(0);
  105.     for(int i = 1; i <= n; i++) {
  106.         while(t[s.top()] <= t[i]) {
  107.             s.pop();
  108.         }
  109.         L[i - 1] = s.top() - 1;
  110.         s.push(i);
  111.     }
  112.     while(!s.empty()) {
  113.         s.pop();
  114.     }
  115.     s.push(n + 1);
  116.     for(int i = n; i > 0; i--) {
  117.         while(t[s.top()] <= t[i]) {
  118.             s.pop();
  119.         }
  120.         R[i - 1] = s.top() - 1;
  121.         s.push(i);
  122.     }
  123.    
  124.     if((int) st.size() == 1) {
  125.         solve_subtask2();
  126.         return 0;
  127.     }
  128.     else if(n <= 5005){
  129.         memset(dp, -1, sizeof dp);
  130.         cout << rec(n - 1, n - 1) << endl;
  131.     }
  132.     else {
  133.         build_tree(0, n - 1, 1);
  134.         map<int, int> m;
  135.         for(int i = 0; i < n; i++) {
  136.             m[a[i]] = i;
  137.         }
  138.        
  139.         for(int i = 0; i < n; i++) {
  140.             map<int, int>::iterator it = m.find(b[i]);
  141.             if(it != m.end()) {
  142.                 int idx = it->second;
  143.                 if(L[idx] < i and i < R[idx]) {
  144.                     int dp = query(0, idx, 0, n - 1, 1);
  145.                     update(idx, dp + 1, 0, n - 1, 1);
  146.                 }
  147.             }
  148.         }
  149.         cout << query(0, n - 1, 0, n - 1, 1) << endl;
  150.     }
  151.    
  152.     return 0;
  153. }
  154.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement