제출 #1342994

#제출 시각아이디문제언어결과실행 시간메모리
1342994WarinchaiFinancial Report (JOI21_financial)C++20
100 / 100
1495 ms74272 KiB
#include<bits/stdc++.h>
using namespace std;

int a[300005];
int dp[300005];
multiset<int>ms[300005];
vector<int>dpos[600005];

struct segtree{
    int info[1200005];
    void upd(int st,int en,int i,int pos,int val){
        if(st>pos||en<pos)return;
        if(st==en)return info[i]=val,void();
        int m=(st+en)/2;
        upd(st,m,i*2,pos,val);
        upd(m+1,en,i*2+1,pos,val);
        info[i]=max(info[i*2],info[i*2+1]);
    }
    int fans(int st,int en,int i,int l,int r){
        if(st>r||en<l)return 0;
        if(st>=l&&en<=r)return info[i];
        int m=(st+en)/2;
        return max(fans(st,m,i*2,l,r),fans(m+1,en,i*2+1,l,r));
    }
}tr,pos;

int n,d;

void add(int x,int val){
    ms[x].insert(val);
    tr.upd(1,n,1,x,*(prev(ms[x].end())));
}

set<int>s;

void del(int x,int val){
    assert(ms[x].lower_bound(val)!=ms[x].end()&&*ms[x].lower_bound(val)==val);
    ms[x].erase(ms[x].lower_bound(val));
    if(ms[x].empty())tr.upd(1,n,1,x,0);
    else tr.upd(1,n,1,x,*(prev(ms[x].end())));
    //cerr<<"del:"<<x<<" "<<*(ms[x].end())<<"\n";
}

int wtf[300005];

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>d;
    vector<int>v;
    for(int i=1;i<=n;i++)cin>>a[i],v.push_back(a[i]);
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
    for(int i=1;i<=n;i++)a[i]=lower_bound(v.begin(),v.end(),a[i])-v.begin()+1;
    /*for(int i=n;i>=1;i--){
        while(!s.empty()&&s.front()-i>d)s.pop_front();
        int prv=i+d+1;
        while(!s.empty()&&a[i]>=a[s.back()])prv=max(prv,wtf[s.back()]),s.pop_back();
        s.push_back(i);
        dpos[prv].push_back(i);
        wtf[i]=prv;
    }*/
    //for(int i=1;i<=n;i++)cerr<<wtf[i]<<" ";
    //cerr<<"\n";
    vector<pair<int,int>>aa;
    for(int i=1;i<=n;i++)aa.push_back({a[i],-i});
    sort(aa.begin(),aa.end());
    s.insert(0);
    s.insert(n+1);
    for(auto [temp,id]:aa){
        id=-id;
        auto it=s.insert(id).first;
        auto nxt=next(it);
        auto prv=prev(it);
        pos.upd(1,n,1,id,id-*prv);
        pos.upd(1,n,1,*nxt,*nxt-id);
        //for(int i=1;i<=n;i++)cerr<<pos.fans(1,n,1,i,i)<<" ";
        //cerr<<"\n";
        int st=id+1,en=n,ans=n+1;
        while(st<=en){
            int m=(st+en)/2;
            if(pos.fans(1,n,1,id+1,m)>d){
                en=m-1;
                ans=m;
            }else{
                st=m+1;
            }
        }
        auto itr=prev(s.lower_bound(ans));
        ans=*itr+d+1;
        wtf[id]=ans;
        dpos[ans].push_back(id);
    }
    //for(int i=1;i<=n;i++)cerr<<wtf[i]<<" ";
    //cerr<<"\n";
    /*for(int i=n;i>=1;i--){
        wtf[i]=i+d+1;
        int dis=0;
        int j=0;
        for(j=i+1;j<=n;j++){
            if(a[i]>=a[j]){
                dis=0;
            }else{
                dis++;
            }
            if(dis==d)break;
        }
        wtf[i]=j+1;
        //cerr<<"i:"<<i<<" "<<j+1<<"\n";
        dpos[wtf[i]].push_back(i);
    }*/
    deque<int>dq;
    for(int i=1;i<=n;i++){
        for(auto x:dpos[i]){
            del(a[x],dp[x]);
        }
        int temp=tr.fans(1,n,1,1,a[i]-1);
        //cerr<<"temp:"<<temp<<"\n";
        dp[i]=temp+1;
        add(a[i],dp[i]);
    }
    int ans=tr.fans(1,n,1,1,n);
    cout<<ans;
}
#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...