NOI.ac #8 小w、小j和小z LIS

传送门

题意:在一个数轴上,给出$N$个人的初始位置与速度(速度有方向),求最大的时间使得存在$N-K$个人在这一段时间内两两没有相遇。$1 \leq K \leq N \leq 10^5$


显然有二分性质,考虑二分答案,接着考虑check过程。

考虑先按照位置排序,然后我们能够发现:如果两个人能够相遇,那么它们的位置大小顺序就会发生变化(也就是产生一个逆序对)

然后就能够发现:最多的互相没有相遇的人在新的位置序列上体现为最长上升子序列,然后就能够通过$O(nlogn)$转移得到答案。

 1 #include<bits/stdc++.h>
 2 #define ld long double
 3 using namespace std;
 4 
 5 inline int read(){
 6     int a = 0;
 7     bool f = 0;
 8     char c = getchar();
 9     while(!isdigit(c)){
10         if(c == '-')
11             f = 1;
12         c = getchar();
13     }
14     while(isdigit(c)){
15         a = (a << 3) + (a << 1) + (c ^ '0');
16         c = getchar();
17     }
18     return f ? -a : a;
19 }
20 
21 const ld eps = 1e-10;
22 const int MAXN = 100010;
23 struct peo{
24     int pos , v;
25 }now[MAXN];
26 ld minN[MAXN];
27 int N , K , cnt;
28 
29 bool operator <(peo a , peo b){
30     return a.pos < b.pos;
31 }
32 
33 bool cmp(ld a , ld b){
34     return a + eps > b && a - eps < b;
35 }
36 
37 bool check(ld mid){
38     cnt = 0;
39     for(int i = 1 ; i <= N ; i++){
40         ld t = now[i].pos + now[i].v * mid;
41         int k = lower_bound(minN , minN + cnt + 1 , t - eps) - minN;
42         if(k > cnt || cmp(minN[k] , t) == 0){
43             minN[k] = t;
44             if(k > cnt)
45                 ++cnt;
46         }
47     }
48     return cnt + K >= N;
49 }
50 
51 int main(){
52     N = read();
53     K = read();
54     for(int i = 1 ; i <= N ; i++){
55         now[i].pos = read();
56         now[i].v = read();
57     }
58     sort(now + 1 , now + N + 1);
59     ld L = 0 , R = 2e9 + 1;
60     minN[0] = -1e30;
61     while(R - L > eps){
62         ld mid = (L + R) / 2;
63         check(mid) ? L = mid : R = mid;
64     }
65     if(R > 2e9)
66         puts("Forever");
67     else
68         printf("%Lf" , L);
69     return 0;
70 }

 

转载于:https://www.cnblogs.com/Itst/p/9818322.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值