Submission #1126033

#TimeUsernameProblemLanguageResultExecution timeMemory
1126033AverageAmogusEnjoyerFinancial Report (JOI21_financial)C++17
100 / 100
493 ms25100 KiB
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template<class T> bool cmin(T &i, T j) { return i > j ? i=j,true:false; }
template<class T> bool cmax(T &i, T j) { return i < j ? i=j,true:false; }

mt19937 mrand(chrono::steady_clock::now().time_since_epoch().count());
uniform_int_distribution<int> ui(0, 1 << 30);

int rng() { 
    return ui(mrand);
}

struct segment2 {
    int n;
    vector<int> st;
    segment2(int N) {
        n=N;
        st.resize(4*n);
    }
    int query(int l,int r,int u,int tl,int tr) {
        if (l > r)
            return 0;
        if (l == tl && r == tr)
            return st[u];
        int mid=(tl+tr)/2;
        return max(query(l,min(mid,r),2*u,tl,mid),query(max(mid+1,l),r,2*u+1,mid+1,tr));
    }
    int query(int l,int r) {
        return query(l,r,1,0,n-1);
    }
    void upd(int p,int x,int u,int tl,int tr) {
        if (tl == tr) {
            st[u]=x;
            return;
        }
        int mid=(tl+tr)/2;
        if (p <= mid)
            upd(p,x,2*u,tl,mid);
        else
            upd(p,x,2*u+1,mid+1,tr);
        st[u]=max(st[2*u],st[2*u+1]);
    }
    void upd(int p,int x) {
        upd(p,x,1,0,n-1);
    }
};

struct DSU {
    int n;
    vector<int> sz,par;
    vector<int> lef;
    DSU(int N) {
        n=N;
        sz.assign(n,1);
        par.resize(n);
        iota(par.begin(),par.end(),0);
        lef=par;
    }
    int get(int u) {
        return par[u]==u?u:par[u]=get(par[u]);
    }
    void unite(int u,int v) {
        u=get(u),v=get(v);
        if (u==v) return;
        if (sz[u]<sz[v]) swap(u,v);
        sz[u]+=sz[v];
        par[v]=u;
        lef[u]=min(lef[u],lef[v]);
    }
};

int main() {
    ios_base::sync_with_stdio(false); 
    cin.tie(nullptr);
    int n,k;
    cin >> n >> k;
    vector<int> a(n);
    vector<int> order(n);
    for (int i=0;i<n;i++)
        cin >> a[i];
    iota(order.begin(),order.end(),0);
    sort(order.begin(),order.end(),[&](int i,int j) {
        if (a[i]==a[j])
            return i > j;
        return a[i] < a[j];
    });
    segment2 dp(n);
    set<int> active;
    DSU dsu(n);
    for (int t=0;t<n;t++) {
        int i=order[t];
        auto it=active.lower_bound(i);
        if (it!=active.end() && *it <= i + k) dsu.unite(i,*it);
        if (it!=active.begin() && *prev(it) >= i - k) dsu.unite(*prev(it),i);
        int l=dsu.lef[dsu.get(i)];
        // cout << l << endl;
        dp.upd(i,dp.query(l,i)+1);
        active.insert(i);
    }
    cout << dp.query(0,n-1) << 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...