제출 #1324293

#제출 시각아이디문제언어결과실행 시간메모리
1324293ereringExam (eJOI20_exam)C++20
100 / 100
357 ms197636 KiB
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define pb push_back
const int N=1e5+5,MAXA=1e6+5,inf=1e9,MOD=1e9+7;
int n,a[N],b[N],lft[N],rt[N],dp[N],dp2[N],suff[5005][5005],lst[N],seen[N],seg[N*4],offset=1;
vector<int> posb[N],posa[N];
void update(int idx,int val){
    idx+=offset;
    seg[idx]=max(seg[idx],val);
    idx/=2;
    while(idx>0){
        seg[idx]=max(seg[idx*2],seg[idx*2+1]);
        idx/=2;
    }
}
int query(int node,int qlo,int qhi,int lo,int hi){
    if(lo>=qlo && hi<=qhi)return seg[node];
    if(lo>qhi || hi<qlo)return 0;
    int mid=(lo+hi)/2;
    return max(query(node*2,qlo,qhi,lo,mid),query(node*2+1,qlo,qhi,mid+1,hi));
}
signed main(){
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cin>>n;
    while(offset<=n)offset*=2;
    deque<pair<int,int>> dq={{inf,0}};
    set<int> comp;
    map<int,bool> seeen;
    bool sub4=1;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        if(seeen[a[i]])sub4=0;
        seeen[a[i]]=1;
        comp.insert(a[i]);
    }
    for(int i=1;i<=n;i++)cin>>b[i];
    map<int,int> id;
    int cnt=1;
    for(auto i:comp)id[i]=cnt++;
    for(int i=1;i<=n;i++){
        a[i]=id[a[i]];
        while(a[i]>=dq.back().first)dq.pop_back();
        lft[i]=dq.back().second+1;
        dq.pb({a[i],i});
        posa[a[i]].pb(i);
    }
    dq={{inf,n+1}};
    for(int i=n;i>0;i--){
        while(a[i]>=dq.front().first)dq.pop_front();
        rt[i]=dq.front().second-1;
        dq.push_front({a[i],i});
    }
    bool flag=1;
    for(int i=1;i<=n;i++){
        b[i]=id[b[i]];
        if(i>1 && b[i]!=b[i-1])flag=0;
        seen[a[i]]=i;
        lst[i]=seen[b[i]];
        posb[b[i]].pb(i);
    }
    if(flag){
        flag=0;
        bool can[n+1];
        for(int i=1;i<=n;i++){
            if(a[i]==b[i])flag=1;
            else if(a[i]>b[i])flag=0;
            can[i]=flag;
        }
        int ans=0;
        for(int i=n;i>0;i--){
            if(a[i]==b[i])flag=1;
            else if(a[i]>b[i])flag=0;
            can[i]|=flag;
            if(can[i])ans++;
        }
        cout<<ans;
        return 0;
    }
    if(sub4){
        vector<int> vec;
        map<int,int> pos;
        for(int i=1;i<=n;i++)pos[a[i]]=i;
        for(int i=1;i<=n;i++){
            int j=pos[b[i]];
            if(lft[j]<=i && rt[j]>=i)vec.pb(j);
        }
        for(auto i:vec)update(i,query(1,0,i,0,offset-1)+1);
        cout<<query(1,0,offset-1,0,offset-1);
        return 0;
    }
    for(int i=n;i>0;i--){
        suff[b[i]][i]++;
        for(int j=1;j<=n;j++)suff[j][i]+=suff[j][i+1];
    }
    /*
     * dp[j]=max(dp[j],dp[k]+#of matches of a[i] from (k+1 to j)
     *  #of matches from k+1 to j = suff[a[i]][k+1]-suff[a[i]][j+1]
     *  dp[k]+suff[a[i]][k+1]-suff[a[i]][j+1]
     *  maximize dp[k]+suff[a[i]][k+1]
     */
    for(int i=1;i<=n;i++){
        int mx=-inf,last=lst[i];
        for(int j=lft[i];j<i;j++){
            mx=max(mx,dp[j-1]+suff[a[i]][j]);
            dp[j]=max(dp[j],mx-suff[a[i]][j+1]);
        }
        dp[i]=dp[i-1]+(a[i]==b[i]);
        if(last!=0 && rt[last]>=i){
            dp2[i]=dp[last-1]+suff[b[i]][last]-suff[b[i]][i+1];
            for(int j=last;j<i;j++){
                if(b[j]>b[i])dp2[i]=max(dp2[i],dp2[j]+suff[b[i]][j+1]-suff[b[i]][i+1]);
          //      if(i==n)cout<<dp2[i]<<' '<<suff[b[i]][j+1]<<' '<<suff[b[i]][i+1]<<' '<<dp2[j]<<' '<<j<<endl;
            }
        }
        dp[i]=max(dp[i],dp2[i]);
       // if(i==n)cout<<dp2[i]<<endl;
    }
    cout<<dp[n];
}
#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...