• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
jacklee404
Never Stop!
博客园    首页    新随笔    联系   管理    订阅  订阅
HBCPC 2020 phobia 二分答案+最长上升子序列

HBCPC 2020 phobia

题目

People with social phobia hate the moment when meeting some acquaintances on the street. So they will try to avoid any chance of making such things happen.

Though hate sudden encounters, people with social phobia still can't stay at home all the time. In order to keep physical health, they will take walks from time to time. The position of each one's house is known, which can be seen as a point on a number axis. We also learned that everyone will move at a constant speed when they take walks.

Now you are given the positions of their houses and their walking speed, and you are able to choose and order k persons to stay home. Your task is to find out, if the remaining persons start to take walks at the same time, for how long at most they can walk without meeting anyone?

Input Format

The first line contains two integers n,k(1≤n≤105,0≤k≤n), the total number of persons and the number of persons you can order to stay home.

Then n lines follow, each line contains two integers x,v(∣x∣,∣v∣≤109), denoting one person's starting position and walking speed.

It is guaranteed that at the beginning there can be only at most one person at each position of the number axis .

Output Format

Print one decimal number, the longgest time they may walk without meeting anyone. If they may keep walking forever without meeting anyone, print -1. Your answer is considered correct if the relative or absolute error is below 10−4.

Sample Input

-1

代码长度限制

16 KB

时间限制

5000 ms

内存限制

512 MB

思路

​ 按初始位置给每个人排序, 经过 \(t\)秒后, 在给每个人排序, 每个人的编号不变, 问我们抹去多少个编号能够使该序列升序,显然等于\(n - siz(LIS)\), LIS (最长上升子序列), 我们对时间二分,显然答案满足二段性, 如下图:

image-20230516212518279

总复杂度\(O(nlog^2n)\)

Code

#include <bits/stdc++.h>
#define ff first
#define ss second

using i64 = long long;

const int N = 1e5 + 10;

const double EPS = 1e-6;

typedef std::pair<i64, i64> PII;

struct node {
	int id;
	double pos, v, ipos;

	bool operator<(const node t) const {
		if (pos == t.pos) {
			return id > t.id;
		}
		return pos < t.pos;
	}
};

int n, k;

node a[N];

/*
	check O(nlogn)
	binary-search O(logn) calculate LIS

	--> nlog^2n
*/

bool check(double time) {
	static int stk[N];

	int len = 0;
    
	for (int i = 1; i <= n; i ++) {
		a[i].pos = a[i].ipos + time * a[i].v;
	}

	std::sort(a + 1, a + 1 + n);

	stk[0] = -1e9;

	for (int i = 1; i <= n; i ++) {
		int l = 0, r = len;

		while (l < r) {
			int mid = l + r + 1 >> 1;
			if (stk[mid] < a[i].id) l = mid;
			else r = mid - 1;
		}

		stk[l + 1] = a[i].id;

		len = std::max(len, l + 1);
	}
    
	return n - len <= k;
}

int main() {
	std::cin >> n >> k;

	for (int i = 1; i <= n; i ++) {
		std::cin >> a[i].pos >> a[i].v;

		a[i].ipos = a[i].pos;
	}

	std::sort(a + 1, a + 1 + n);

	for (int i = 1; i <= n; i ++) {
		a[i].id = i;
	}

	double l = 0, r = 2e9 + 10;

	int cnt = 1;

	while (r - l > EPS) {
		double mid = (l + r) / 2;
		if (check(mid)) l = mid;
		else r = mid;
	}

	if (r == 2e9 + 10) {
		std::cout << -1;
	} else {
		printf("%.4lf", l);
	}
}
posted on 2023-05-16 21:28  Jack404  阅读(16)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3