This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |