제출 #1128305

#제출 시각아이디문제언어결과실행 시간메모리
1128305ByeWorld밀림 점프 (APIO21_jumps)C++20
100 / 100
1006 ms104068 KiB
#include "jumps.h"
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define fi first
#define se second
#define lf (id<<1)
#define rg ((id<<1)|1)
#define md ((l+r)>>1)
#define ld long double
using namespace std;
typedef pair<int,int> pii;
typedef pair<char,char> pcc;
typedef pair<int,pii> ipii;
typedef pair<pii,pii> ipiii;
const int MAXN = 2e5+10;
const int LOG = 20;
const int MAXA = 1e6;
const int INF = 2e9;

int n, h[MAXN];
int le[MAXN], ri[MAXN], anc[MAXN][LOG+5];
int up[MAXN][LOG+5], dw[MAXN][LOG+5];
pii mx[MAXN][LOG+5];

pii MX(int le, int ri){
	if(le > ri) return pii(-INF, 0);
	int len = log2(ri-le+1);
	return max(mx[le][len], mx[ri-(1<<len)+1][len]);
}
void init(int N, std::vector<int> H) {
	n = N;
	for(int i=1; i<=n; i++){
		h[i] = H[i-1];
		mx[i][0] = {h[i], i};
	}
	for(int j=1; j<LOG; j++){
		for(int i=1; i+(1<<j)-1<=n; i++){
			mx[i][j] = max(mx[i][j-1], mx[i+(1<<(j-1))][j-1]);
		}
	}

	h[0] = h[n+1] = -INF;
	ri[n+1] = n+1;
	for(int j=0; j<LOG; j++)
		for(int i=0; i<=n+1; i++)
			anc[i][j] = up[i][j] = n+1,
			dw[i][j] = 0; 

	vector <pii> vec; 
	for(int i=n; i>=1; i--){
		while(!vec.empty() && h[i] > vec.back().fi) vec.pop_back();
		if(!vec.empty()){
			ri[i] = vec.back().se; 
			// cout << i << ' ' << vec.back().se << " pp\n";
		} else ri[i] = n+1;
		up[i][0] = ri[i];
		vec.pb({h[i], i});
	}
	vec.clear(); 
	for(int i=1; i<=n; i++){
		while(!vec.empty() && h[i] > vec.back().fi) vec.pop_back();
		if(!vec.empty()){
			le[i] = vec.back().se;
			// cout << i << ' ' << vec.back().se << " pp\n";
		} else le[i] = 0;
		dw[i][0] = le[i];
		vec.pb({h[i], i});
	}
		
	
	for(int i=1; i<=n; i++){
		if(h[le[i]] > h[ri[i]]) anc[i][0] = le[i];
		else anc[i][0] = ri[i];
	}
	for(int j=1; j<LOG; j++)
		for(int i=1; i<=n; i++)
			anc[i][j] = anc[ anc[i][j-1] ][j-1],
			up[i][j] = up[ up[i][j-1] ][j-1],
			dw[i][j] = dw[ dw[i][j-1] ][j-1];
}

int cost(int sta, int en){
	int tot = 0;
	for(int i=LOG-1; i>=0; i--){
		if(anc[sta][i]!=n+1 && anc[sta][i]!=0 && h[ anc[sta][i] ] <= h[en]){
			sta = anc[sta][i];
			tot += (1<<i);
		}
	}
	for(int i=LOG-1; i>=0; i--){
		if(up[sta][i]!=n+1 && up[sta][i] <= en){
			sta = up[sta][i];
			tot += (1<<i);
		}
	}
	if(sta == en) return tot;
	return INF;
}
int minimum_jumps(int A, int B, int C, int D) {
	// goto right
	A++; B++; C++; D++;
	if(B == C-1){
		if(C<=ri[B] && ri[B]<=D) return 1;
		return -1;
	}

	int mx = MX(B+1, C-1).fi;
	int jump = 0, idxj = 0;
	if(MX(A, B).fi > mx){ // bisa langsung
		int l=A, r=B, mid=0, cnt=A;
		while(l<=r){ // cari yg paling kanan lebih dr mx
			mid = md;
			if(MX(mid, B).fi > mx) l = mid+1, cnt = mid;
			else r = mid-1;
		}
		jump = 0; idxj = cnt;
	} else { // harus ke kiri dulu
		int nw = MX(A, B).se; // dari range max

		int l=1, r=A-1, mid=0, cnt=0;
		while(l<=r){ // paling kanan yg more
			mid = md;
			if(MX(mid, B).fi > mx) l = mid+1, cnt = mid;
			else r = mid-1;
		}
		// harus ke cnt
		for(int i=LOG-1; i>=0; i--){ // ke kiri
			if(anc[nw][i]!=n+1 && anc[nw][i]!=0 && 
				h[ anc[nw][i] ] <= h[cnt]){ // ke cnt
				nw = anc[nw][i]; jump += (1<<i);
			}
		}
		idxj = cnt;
	}
	// cout << idxj << " idx\n";
	// 	cout << jump << " jump\n";
	int ans = INF;
	if(idxj!=0 && idxj!=n+1
		&& C<=ri[idxj] && ri[idxj]<=D) ans = jump+1;

	int l=A, r=B, mid=0, cnt=B;
	while(l<=r){ // cari max range yg < mx
		mid = md;
		if(MX(mid, B).fi < mx) cnt = mid, r = mid-1;
		else l = mid+1;
	}
	int sta = MX(cnt, B).se;
	// cout << sta << " sta\n";

	l=C, r=D, mid=0, cnt=C;
	while(l<=r){
		mid = md;
		if(MX(C, mid).fi > mx) cnt = mid, r = mid-1;
		else l = mid+1;
	}
	if(MX(C, D).fi < mx) return -1; // gk bisa ke sana

	int en = cnt;

	ans = min(ans, cost(sta, en));

	return (ans > n ? -1 : 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...
#Verdict Execution timeMemoryGrader output
Fetching results...