Submission #951538

#TimeUsernameProblemLanguageResultExecution timeMemory
951538hengliaoRainforest Jumps (APIO21_jumps)C++17
81 / 100
4011 ms94492 KiB
#include<bits/stdc++.h> using namespace std; #define F first #define S second #define pb push_back #define vll vector<ll> #define pll pair<ll, ll> typedef long long ll; const ll mxN=2e5+5; const ll inf=1e9; ll n; vector<ll> h; vll adj[mxN]; ll r[mxN]; ll l[mxN]; vll dis; bool cool; ll up[mxN][20]; ll up2[mxN][20]; ll bg[mxN]; ll sm[mxN]; struct segtree{ vll tree; ll treelen; void init(ll s){ treelen=s+1; while(__builtin_popcount(treelen)!=1){ treelen++; } tree.resize(2*treelen); } void update(ll idx, ll val){ ll tar=idx+treelen; while(tar>0){ tree[tar]=max(tree[tar], val); tar/=2; } } ll getmax(ll idx, ll low, ll high, ll qlow, ll qhigh){ if(low>=qlow && high<=qhigh){ return tree[idx]; } if(low>qhigh || high<qlow){ return 0; } ll mid=(low+high)/2; return max(getmax(2*idx, low, mid, qlow, qhigh), getmax(2*idx+1, mid+1, high, qlow, qhigh)); } }; int rand(int a, int b){ return a+rand()%(b-a+1); } segtree seg; void init(int tn, vector<int> th){ n=tn; h.resize(n); cool=1; seg.init(n); for(ll i=0;i<n;i++){ h[i]=th[i]; if(h[i]!=i+1){ cool=0; } seg.update(i, h[i]); } vector<ll> stk; for(ll i=0;i<n;i++){ if(!stk.empty()){ ll lef=0, rig=stk.size()-1; ll tep=inf; while(lef<=rig){ ll mid=(lef+rig)/2; if(stk[mid]>h[i]){ tep=min(tep, stk[mid]); lef=mid+1; } else{ rig=mid-1; } } l[h[i]]=tep; } else{ l[h[i]]=inf; } while(!stk.empty() && stk.back()<h[i]){ stk.pop_back(); } stk.pb(h[i]); } stk.clear(); for(ll i=n-1;i>=0;i--){ if(!stk.empty()){ ll lef=0, rig=stk.size()-1; ll tep=inf; while(lef<=rig){ ll mid=(lef+rig)/2; if(stk[mid]>h[i]){ tep=min(tep, stk[mid]); lef=mid+1; } else{ rig=mid-1; } } r[h[i]]=tep; } else{ r[h[i]]=inf; } while(!stk.empty() && stk.back()<h[i]){ stk.pop_back(); } stk.pb(h[i]); } for(ll i=1;i<=n;i++){ if(l[i]!=inf){ adj[i].pb(l[i]); } if(r[i]!=inf){ adj[i].pb(r[i]); } } for(ll i=1;i<=n;i++){ if(l[i]==inf && r[i]==inf){ bg[i]=inf; sm[i]=inf; } else if(l[i]==inf){ bg[i]=r[i]; sm[i]=inf; } else if(r[i]==inf){ bg[i]=l[i]; sm[i]=inf; } else{ bg[i]=max(l[i], r[i]); sm[i]=min(l[i], r[i]); } up[i][0]=bg[i]; up2[i][0]=sm[i]; } for(ll i=1;i<20;i++){ for(ll j=1;j<=n;j++){ if(up[j][i-1]!=inf) up[j][i]=up[up[j][i-1]][i-1]; else up[j][i]=inf; } } for(ll i=1;i<20;i++){ for(ll j=1;j<=n;j++){ if(up2[j][i-1]!=inf) up2[j][i]=up2[up2[j][i-1]][i-1]; else up2[j][i]=inf; } } //cout<<"initializing\n"; //for(ll i=1;i<=n;i++){ //cout<<i<<' '<<l[i]<<' '<<r[i]<<'\n'; //} } int minimum_jumps(int a, int b, int c, int d){ if(cool) return c-b; if(c==d){ ll ta=a; a=h[b]; c=h[c]; ll lef=ta, rig=b; while(lef<=rig){ ll mid=(lef+rig)/2; if(seg.getmax(1, 0, seg.treelen-1, mid, b)<c){ a=max(a, (int)seg.getmax(1, 0, seg.treelen-1, mid, b)); rig=mid-1; } else{ lef=mid+1; } } ll ans=0; for(ll i=19;i>=0;i--){ if(up[a][i]<=c){ ans+=(1LL<<i); a=up[a][i]; } } for(ll i=19;i>=0;i--){ if(up2[a][i]<=c){ ans+=(1LL<<i); a=up2[a][i]; } } if(a!=c){ return -1; } else{ return (int) ans; } } dis=vll(n+1, inf); queue<pll> q; for(ll i=a;i<=b;i++){ q.push({h[i], 0}); } while(!q.empty()){ pll cur=q.front(); q.pop(); if(dis[cur.F]!=inf){ continue; } dis[cur.F]=cur.S; for(auto it:adj[cur.F]){ q.push({it, cur.S+1}); } } ll re=inf; for(ll i=c;i<=d;i++){ re=min(re, dis[h[i]]); //cout<<h[i]<<' '<<dis[h[i]]<<'\n'; } if(re==inf) return -1; else return (int) re; } /*int minimum_jumps2(int a, int b, int c, int d){ if(cool) return c-b; dis=vll(n+1, inf); queue<pll> q; for(ll i=a;i<=b;i++){ q.push({h[i], 0}); } while(!q.empty()){ pll cur=q.front(); q.pop(); if(dis[cur.F]!=inf){ continue; } dis[cur.F]=cur.S; for(auto it:adj[cur.F]){ q.push({it, cur.S+1}); } } ll re=inf; for(ll i=c;i<=d;i++){ re=min(re, dis[h[i]]); //cout<<h[i]<<' '<<dis[h[i]]<<'\n'; } if(re==inf) return -1; else return (int) re; } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n, q; n=10; q=100; vector<int> h(n); for(ll i=0;i<n;i++){ h[i]=i+1; } random_shuffle(h.begin(), h.end()); init(n, h); for(ll k=0;k<q;k++){ int a, b, c, d; a=rand(0, n-2); b=a; c=rand(b+1, n-1); d=c; cout<<a<<' '<<c<<'\n'; if(minimum_jumps(a, b, c, d)!=minimum_jumps2(a, b, c, d)){ cout<<"found wrong\n"; cout<<a<<' '<<c<<'\n'; for(ll j=0;j<n;j++){ cout<<h[j]<<' '; } cout<<'\n'; cout<<minimum_jumps(a, b, c, d)<<' '<< minimum_jumps2(a, b, c, d)<<'\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...
#Verdict Execution timeMemoryGrader output
Fetching results...