【APIO2021】雨林跳跃

时间:2021-06-02 13:32:29   收藏:0   阅读:0
#include <bits/stdc++.h>
#include "jumps.h"
using namespace std;

typedef pair <int, int> pii;

const int N = 6e5 + 10;

int n, h[N], l[N][20], r[N][20], f[N][20], top, s[N], b[N];

pii g[N][20];

pii qmax_(int l, int r) {
	int k = b[r - l + 1];
	return max(g[l][k], g[r - (1<<k) + 1][k]);
}

void init(int N, vector <int> H) {
	n = N, b[0] = -1;
	
	for (int i = 1; i <= n; i++)	
		h[i] = H[i - 1], g[i][0] = pii(h[i], i), b[i] = b[i>>1] + 1;
		
	for (int k = 1; k <= b[n]; k++)
		for (int i = 1; i + (1<<k) - 1 <= n; i++)
			g[i][k] = max(g[i][k - 1], g[i + (1<<k - 1)][k - 1]);
		
	for (int i = 1; i <= n; i++) {
		while (top && h[s[top]] < h[i])
			top--;
		
		l[i][0] = top ? s[top] : i;
		s[++top] = i;
	}
	
	top = 0;
	
	for (int i = n; i; i--) {
		while (top && h[s[top]] < h[i])
			top--;
		
		f[i][0] = r[i][0] = top ? s[top] : i;
		s[++top] = i;
	}
	
	for (int k = 1; k <= b[n]; k++)
		for (int i = 1; i <= n; i++) {
			l[i][k] = min(l[l[i][k - 1]][k - 1], l[r[i][k - 1]][k - 1]);
			r[i][k] = max(r[l[i][k - 1]][k - 1], r[r[i][k - 1]][k - 1]);
			f[i][k] = f[f[i][k - 1]][k - 1];
		}
}

int minimum_jumps(int A, int B, int C, int D) {
	A++, B++, C++, D++;
	
	int mx = qmax_(C, D).first, L = A, R = B + 1;
	
//	cout<<mx<<‘ ‘<<qmax_(B, C - 1).first<<‘\n‘;
	
	if (qmax_(B, C - 1).first > mx)
		return -1;
		
	while (L < R) {
		int mid = (L + R)>>1;
		
		if (qmax_(mid, R).first > mx)
			L = mid + 1;
		else	
			R = mid;
	}
	
	int x = qmax_(L, B).second, ans = 0, y = x;
	
	for (int k = b[n]; k >= 0; k--)
		if (max(r[x][k], r[y][k]) < C) {
			ans += 1<<k;
			int p = min(l[x][k], l[y][k]), q = max(r[x][k], r[y][k]);
			x = p, y = q;
		}
	
	if (h[y] > h[x]) 
		return ans + 1;
	
	if (f[x][0] >= C && f[x][0] <= D)
		return ans + 1;
	
	for (int k = b[n]; k >= 0; k--)
		if (f[y][k] < C)
			y = f[y][k], ans += 1<<k;
	
	return ans + 1;
}
评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!