Submission #1144422

#TimeUsernameProblemLanguageResultExecution timeMemory
1144422Noproblem29Giraffes (JOI22_giraffes)C++20
100 / 100
1760 ms4340 KiB
#include<bits/stdc++.h>
using namespace std;
#ifndef BADGNU
#pragma GCC target("sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
#endif
#pragma GCC optimize("Ofast,unroll-loops,fast-math,O3")
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp> 
using namespace __gnu_pbds;
#define ll long long
#define int ll
#define ld long double
#define y1 cheza
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
template<class T> using ordered_multiset = tree<T,null_type,less_equal<T>,rb_tree_tag,tree_order_statistics_node_update>;
const int N=8005;
const int M=5001;
const int B=447;
const int mod=998244353;
const ll INF=1e9;
const int dx[]={1,-1,0,0};
const int dy[]={0,0,1,-1};
const double eps=1e-6;
struct ki{
    int x,y,w;
    ki():x(0),y(0),w(0){}
    ki(int _x,int _y,int _w):x(_x),y(_y),w(_w){}
};
struct BIT{
    int sz;
    vector<int>f;
    BIT():sz(0),f(vector<int>()){}
    BIT(int n){
        sz=1;
        while(sz<n){
            sz*=2ll;
        }
        f=vector<int>(sz*2,INF*2);
    }
    void clean(){
        for(int i=0;i<sz*2;i++){
            f[i]=INF*2;
        }
    }
    void upd(int l,int x){
        l+=sz;
        f[l]=min(f[l],x);
        while(l>1){
            l>>=1;
            f[l]=min(f[l*2],f[l*2+1]);
        }
    }
    int get(int l,int r){
        int res=INF*2;
        l+=sz;
        r+=sz;
        while(l!=r){
            if(l&1)res=min(res,f[l++]);
            if(r&1)res=min(res,f[--r]);
            l>>=1;
            r>>=1;
        }
        return res;
    }
};
int n,m;
int p[N];
int dp[4][N];
vector<int>p1,p2;

void test(){
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>p[i];
        p[i]--;
        p1.push_back(i);
        p2.push_back(i);
    }
    sort(p1.begin(),p1.end(),[](int x,int y){
        return x-p[x]<y-p[y];
    });
    sort(p2.begin(),p2.end(),[](int x,int y){
        return x+p[x]<y+p[y];
    });
    int ans=n-1;
    BIT st1(n),st2(n);
    while(ans>=1){
        vector<ki>v,v1,v2;
        for(int mask=0;mask<4;mask++){
            for(int i=0;i<n;i++){
                if(dp[mask][i]!=INF){
                    int x=i-(mask&2?dp[mask][i]:0);
                    int y=p[i]-(mask&1?dp[mask][i]:0);
                    v.push_back({x,y,dp[mask][i]});
                }
                dp[mask][i]=INF;
            }
        }
        v1=v;
        v2=v;
        m=v.size();
        sort(v1.begin(),v1.end(),[](const ki&a,const ki&b){
            return a.x-a.y<b.x-b.y;
        });
        sort(v2.begin(),v2.end(),[](const ki&a,const ki&b){
            return a.x+a.y+a.w<b.x+b.y+b.w;
        });
        
        int posp=0,posv=0;
        // i hate conditions
        st1.clean();
        st2.clean();
        posp=0;
        posv=0;
        while(posp!=n||posv!=m){
            int px=p1[posp],py=p[px];
            int res1=(posp!=n?px-py:INF);
            int res2=(posv!=m?v1[posv].x-v1[posv].y:INF);
            if(res1>=res2){
                st1.upd(v1[posv].x,v1[posv].y+v1[posv].w);
                st2.upd(v1[posv].y+v1[posv].w,-v1[posv].x);
                posv++;
            }
            else{
                dp[0][px]=min(dp[0][px],st1.get(px+1,n)-py);    
                dp[3][px]=min(dp[3][px],px-(-st2.get(0,py)));
                posp++;
            }
        }   
        // still hating
        st1.clean();
        st2.clean();
        posp=n-1;
        posv=m-1;
        while(posp!=-1||posv!=-1){
            int px=p1[posp],py=p[px];
            int res1=(posp!=-1?px-py:-INF);
            int res2=(posv!=-1?v1[posv].x-v1[posv].y:-INF);
            if(res1<=res2){
                st1.upd(v1[posv].y,v1[posv].x+v1[posv].w);
                st2.upd(v1[posv].x+v1[posv].w,-v1[posv].y);
                posv--;
            }
            else{
                dp[0][px]=min(dp[0][px],st1.get(py+1,n)-px);
                dp[3][px]=min(dp[3][px],py-(-st2.get(0,px)));
                posp--;
            }
        }  
        //wtf author
        st1.clean();
        st2.clean();
        posp=0;
        posv=0;
        while(posp!=n||posv!=m){
            int px=p2[posp],py=p[px];
            int res1=(posp!=n?px+py:INF);
            int res2=(posv!=m?v2[posv].x+v2[posv].y+v2[posv].w:INF);
            if(res1>=res2){
                st1.upd(v2[posv].x,-v2[posv].y);
                st2.upd(v2[posv].y,-v2[posv].x);
                posv++;
            }
            else{
                dp[1][px]=min(dp[1][px],py-(-st1.get(px+1,n)));
                dp[2][px]=min(dp[2][px],px-(-st2.get(py+1,n)));
                posp++;
            }
        }   
        // blyaaaaaaaaaaaaa 
        st1.clean();
        st2.clean();
        posp=n-1;
        posv=m-1;
        while(posp!=-1||posv!=-1){
            int px=p2[posp],py=p[px];
            int res1=(posp!=-1?px+py:-INF);
            int res2=(posv!=-1?v2[posv].x+v2[posv].y+v2[posv].w:-INF);
            if(res1<=res2){
                st1.upd(v2[posv].y+v2[posv].w,v2[posv].x+v2[posv].w);
                st2.upd(v2[posv].x+v2[posv].w,v2[posv].y+v2[posv].w);

                posv--;
            }
            else{
                dp[1][px]=min(dp[1][px],st1.get(0,py)-px);
                dp[2][px]=min(dp[2][px],st2.get(0,px)-py);
                posp--;
            }
        }  

        bool ok=1;
        for(int mask=0;mask<4;mask++){
            for(int i=0;i<n;i++){
                int lx=(mask&2?i:n-i-1);
                int rx=(mask&1?p[i]:n-p[i]-1);
                if(dp[mask][i]>min(lx,rx)){
                    dp[mask][i]=INF;
                }
                if(dp[mask][i]!=INF){
                    ok=0;
                }
            }
        }
        if(ok){
            break;
        }

        ans--;
    }
    cout<<ans<<'\n';

}



/*

*/
signed main(){
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    // cout.tie(nullptr);
    int t2=1;
    // cin>>t2;
    for(int i=1;i<=t2;i++){
        test();
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...