Submission #1247570

#TimeUsernameProblemLanguageResultExecution timeMemory
1247570andrei_nExam (eJOI20_exam)C++20
100 / 100
95 ms99144 KiB
#include <bits/stdc++.h>

#define DEFINE_COMBINE(NAME,RES) template<typename T> struct NAME{T operator()(const T&a,const T&b)const{return RES;}};
DEFINE_COMBINE(Plus,a+b)DEFINE_COMBINE(MultiplyCombine,a*b)DEFINE_COMBINE(Xor,a^b)DEFINE_COMBINE(Or,a|b)DEFINE_COMBINE(And,a&b)DEFINE_COMBINE(Max,a<b?b:a)DEFINE_COMBINE(Min,a<b?a:b)
#define DEFINE_UPDATE(NAME,RES) template<typename Node,typename Upd> struct NAME{void operator()(Node&a,const Upd&b)const{RES;}};
DEFINE_UPDATE(Assign,a=b)DEFINE_UPDATE(Add,a+=b)DEFINE_UPDATE(Substract,a-=b)DEFINE_UPDATE(Multiply,a*=b)DEFINE_UPDATE(Divide,a/=b)DEFINE_UPDATE(XorUpdate,a^=b)DEFINE_UPDATE(OrUpdate,a|=b)DEFINE_UPDATE(AndUpdate,a&=b)DEFINE_UPDATE(Maximize,a=(a<b?b:a))DEFINE_UPDATE(Minimize,a=(a<b?a:b))
template<typename Node,typename UpdType,typename Combine,typename Update,const int SIZE>struct FenwickTree{Node v[SIZE+5];Combine comb;Update upd;FenwickTree(){for(int i=0;i<SIZE+5;++i)v[i]=0;}void update(int p,const UpdType&x){for(;p<=SIZE;p+=(p&-p))upd(v[p],x);}Node query(int p)const{Node res=v[p];for(p^=(p&-p);p;p^=(p&-p))res=comb(res,v[p]);return res;}};

using namespace std;

int a[100005], b[100005];
map<int,int> pos;
int dp[5005][5005];
int rmq[17][100005];
int e[100005];
int n;
FenwickTree<int, int, Max<int>, Maximize<int,int>, 100005> aib;

inline int query(const int &a, const int &b)
{
    return max(rmq[e[b-a+1]][a], rmq[e[b-a+1]][b + 1 - (1<<e[b-a+1])]);
}

signed main()
{
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin>>n;
    for(int i=1; i<=n; ++i)
    {
        cin>>a[i];
        rmq[0][i] = a[i];
        pos[a[i]] = i;
    }
    for(int i=1; i<=n; ++i)
        cin>>b[i];
    for(int i=1; i<17; ++i)
        for(int j=1; j+(1<<i)-1 <= n; ++j)
            rmq[i][j] = max(rmq[i-1][j], rmq[i-1][j+(1<<i-1)]);
    for(int i=2; i<=n; ++i)
        e[i] = e[i-1] + ((i & (i-1)) == 0);
    if(count(b+1, b+n+1, b[1]) == n)
    {
        int l = 0, cnt = 0;
        bool have = false;
        for(int i=1; i<=n; ++i)
        {
            if(a[i] == b[1])
                have = true;
            if(a[i] <= b[1])
                ++l;
            else
            {
                if(have) cnt += l;
                l = 0; have = false;
            }
        }
        if(have) cnt += l;
        cout<<cnt;
    }
    else if(n <= 5000)
    {
        for(int i=1; i<=n; ++i)
        {
            for(int j=1; j<=n; ++j)
            {
                dp[i][j] = dp[i][j-1];
                if(a[j] == query(min(i,j), max(i,j)))
                    dp[i][j] = max(dp[i][j], dp[i-1][j] + (a[j] == b[i]));
            }
        }
        cout<<dp[n][n];
    }
    else
    {
        vector<pair<int,int>> p;
        for(int i=1; i<=n; ++i)
        {
            int j = pos[b[i]];
            if(a[j] != query(min(i,j), max(i,j)))
                continue;
            p.emplace_back(i, j);
        }
        sort(p.begin(), p.end());
        for(int i=0; i<p.size(); ++i)
            aib.update(p[i].second, aib.query(p[i].second) + 1);
        cout<<aib.query(n);
    }
    return 0;
}
#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...