Submission #1281425

#TimeUsernameProblemLanguageResultExecution timeMemory
1281425KerimExam (eJOI20_exam)C++17
100 / 100
730 ms99344 KiB
#include "bits/stdc++.h"

using namespace std;
const int N = 1e5+5;
const int K = 5005;
int l[N], r[N], a[N], b[N];
int dp[K][K], n;
int rec(int x, int y){
    if (x > n or y > n)
        return 0;
    int &ret = dp[x][y];
    if (~ret)
        return ret;
    ret = max(rec(x+1, y), rec(x, y+1)); //skip
    if (a[x] == b[y] and l[x] <= y and y <= r[x]) //match
        ret = max(ret, rec(x, y+1) + 1);
    return ret;
}
int F[N];
int tap(int x){
    int res = 0;
    for (;x;x-=x&(-x))
        res = max(res, F[x]);
    return res;
}
void upd(int x, int val){
    for (;x<N;x+=x&(-x))
        F[x] = max(F[x], val);
}
int main(){
    // freopen("file.in", "r", stdin);
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", a+i);
    for (int i = 1; i <= n; i++)
        scanf("%d", b+i);
    a[0] = a[n+1] = 2e9;
    stack<int>st;
    //for left
    st.push(0);
    for (int i = 1; i <= n; i++){
        while (!st.empty() and a[st.top()] <= a[i])
            st.pop();
        l[i] = st.top()+1;
        st.push(i);
    }
    //for right
    while (!st.empty())
        st.pop();
    st.push(n+1);
    for (int i = n; i >= 1; i--){
        while (!st.empty() and a[st.top()] <= a[i])
            st.pop();
        r[i] = st.top()-1;
        st.push(i);
    }
    if (n < K){
        memset(dp, -1, sizeof dp);
        printf("%d\n", rec(0, 0));
    }
    else if (count(b+1, b+n+1, b[1]) == n){//subtask 2
        int found = 0, cnt = 0, answer = 0;
        for (int i = 1; i <= n; i++){
            if (a[i] <= b[i]){
                found |= a[i] == b[i];
                cnt += 1;
            }
            else{
                if (found)
                    answer += cnt;
                cnt = found = 0;
            }
        }
        if (found)
            answer += cnt;
        printf("%d\n", answer);
    }
    else{ //subtask 4
        map<int, int> pos;
        for (int i = 1; i <= n; i++)
            pos[a[i]] = i;
        int answer = 0;
        for (int i = 1; i <= n; i++)
            if (pos.find(b[i]) != pos.end()){
                int j = pos[b[i]];
                if (l[j] <= i and i <= r[j]){
                    int dp = tap(j) + 1;
                    upd(j, dp); 
                    answer = max(answer, dp);
                }
            }
        printf("%d\n", answer);
    }
}

Compilation message (stderr)

exam.cpp: In function 'int main()':
exam.cpp:32:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   32 |     scanf("%d", &n);
      |     ~~~~~^~~~~~~~~~
exam.cpp:34:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   34 |         scanf("%d", a+i);
      |         ~~~~~^~~~~~~~~~~
exam.cpp:36:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   36 |         scanf("%d", b+i);
      |         ~~~~~^~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...