Submission #412231

#TimeUsernameProblemLanguageResultExecution timeMemory
412231Theo830Exam (eJOI20_exam)C++17
77 / 100
162 ms98604 KiB
    #include <bits/stdc++.h>
    using namespace std;
    typedef int ll;
    ll INF = 1e9+7;
    ll MOD = 998244353;
    typedef pair<ll,ll> ii;
    #define iii pair<ii,ll>
    #define f(i,a,b) for(ll i = a;i < b;i++)
    #define pb push_back
    #define vll vector<ll>
    #define F first
    #define S second
    #define all(x) (x).begin(), (x).end()
    ///I hope I will get uprating and don't make mistakes
    ///I will never stop programming
    ///sqrt(-1) Love C++
    ///Please don't hack me
    ///@TheofanisOrfanou Theo830
    ///Think different approaches (bs,dp,greedy,graphs,shortest paths,mst)
    ///Stay Calm
    ///Look for special cases
    ///Beware of overflow and array bounds
    ///Think the problem backwards
    ///Training
    ll seg[400005]={0};
    void update(ll s,ll e,ll qs,ll qe,ll idx,ll k){
        if(s == e && s == qs){
            seg[idx] = max(seg[idx],k);
            return;
        }
        if(qs > e || qe < s){
            return;
        }
        ll mid = (s+e)/2;
        update(s,mid,qs,qe,idx*2,k);
        update(mid+1,e,qs,qe,idx*2+1,k);
        seg[idx] = max(seg[idx*2],seg[idx*2+1]);
    }
    ll query(ll s,ll e,ll qs,ll qe,ll idx){
        if(qs <= s && e <= qe){
            return seg[idx];
        }
        if(qs > e || qe < s){
            return 0;
        }
        ll mid = (s+e)/2;
        ll a = query(s,mid,qs,qe,idx*2);
        ll b = query(mid+1,e,qs,qe,idx*2+1);
        return max(a,b);
    }
    int main(void){
        ios_base::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        ll n;
        cin>>n;
        ll a[n],b[n];
        map<ll,ll>mp;
        bool ok1 = 1,ok2 = 1;
        f(i,0,n){
            cin>>a[i];
            if(mp[a[i]] == 1){
                ok1 = 0;
            }
            mp[a[i]]++;
        }
        f(i,0,n){
            cin>>b[i];
            if(b[i] != b[0]){
                ok2 = 0;
            }
        }
      	if(ok2){
            ll ans = 0;
            ll ok = 0;
            ll posa = 0;
            f(i,0,n){
                if(a[i] > b[0]){
                    ans += posa * ok;
                    ok = 0;
                    posa = 0;
                }
                else{
                    posa++;
                    ok |= (a[i] == b[0]);
                }
            }
            ans += posa * ok;
            cout<<ans<<endl;
            return 0;
        }
        if(ok1 && n > 5000){
            ll l[n],r[n];
            priority_queue<ii,vector<ii>,greater<ii> >pq;
            f(i,0,n){
                pq.push(ii(a[i],i));
                while(pq.top().F < a[i]){
                    r[pq.top().S] = i-1;
                    pq.pop();
                }
            }
            while(!pq.empty()){
                r[pq.top().S] = n-1;
                pq.pop();
            }
            for(ll i=n-1;i >= 0;i--){
                pq.push(ii(a[i],i));
                while(pq.top().F < a[i]){
                    l[pq.top().S] = i+1;
                    pq.pop();
                }
            }
            while(!pq.empty()){
                l[pq.top().S] = 0;
                pq.pop();
            }
            ll ans = 0;
            ll dp[n+1];
            dp[0] = 0;
            f(i,1,n+1){
                dp[i] = 0;
                if(b[i-1] == INF || !(l[b[i-1]-1] <= i-1 && i-1 <= r[b[i-1]-1])){
                    continue;
                }
                dp[i] = query(1,n+1,1,b[i-1],1) + 1;
                update(1,n+1,b[i-1],b[i-1],1,dp[i]);
                ans = max(ans,dp[i]);
            }
            cout<<ans<<endl;
            return 0;
        }
        ll l[n],r[n];
        priority_queue<ii,vector<ii>,greater<ii> >pq;
        f(i,0,n){
            pq.push(ii(a[i],i));
            while(pq.top().F < a[i]){
                r[pq.top().S] = i-1;
                pq.pop();
            }
        }
        while(!pq.empty()){
            r[pq.top().S] = n-1;
            pq.pop();
        }
        for(ll i=n-1;i >= 0;i--){
            pq.push(ii(a[i],i));
            while(pq.top().F < a[i]){
                l[pq.top().S] = i+1;
                pq.pop();
            }
        }
        while(!pq.empty()){
            l[pq.top().S] = 0;
            pq.pop();
        }
        ll dp[n+1][n+1];
        f(i,0,n+1){
            f(j,0,n+1){
                if(i == 0 || j == 0){
                    dp[i][j] = 0;
                }
                else{
                    dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
                    if(a[i-1] == b[j-1] && (l[i-1] <= j-1 && j-1 <= r[i-1])){
                        dp[i][j] = max(dp[i][j],dp[i][j-1] + 1);
                    }
                }
            }
        }
        cout<<dp[n][n]<<endl;
    }
#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...