# NOI热身赛A. 小w、小j和小z

$n \leq 100000$个点在数轴上运动，给初始位置和速度。能删$k$个点，问最晚什么时候发生第一次碰撞。

 1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 //#include<math.h>
5 //#include<set>
6 //#include<queue>
7 //#include<bitset>
8 //#include<vector>
9 #include<algorithm>
10 #include<stdlib.h>
11 using namespace std;
12
13 #define LL long long
15 {
16     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
17     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
18 }
19
20 //Pay attention to '-' , LL and double of qread!!!!
21
22 int n,K;
23 #define maxn 100011
24 struct BIT
25 {
26     int a[maxn],n;
27     void clear(int N) {n=N; memset(a,0,sizeof(a));}
28     void add(int x,int v) {for (;x<=n;x+=x&-x) a[x]=max(a[x],v);}
29     int query(int x) {int ans=0; for (;x;x-=x&-x) ans=max(ans,a[x]); return ans;}
30 }t;
31
32 struct Point{int s,t,v; bool operator < (const Point &b) const {return s<b.s;} }p[maxn];
33 struct TT{int id; double v; bool operator < (const TT &b) const {return v<b.v;} }tt[maxn];
34 int f[maxn];
35 bool check(double T)
36 {
37     t.clear(n);
38     for (int i=1;i<=n;i++) tt[tt[i].id=i].v=p[i].s+p[i].v*T;
39     sort(tt+1,tt+1+n); for (int i=1;i<=n;i++) p[tt[i].id].t=i;
40     int ans=0;
41     for (int i=1;i<=n;i++)
42     {
43         f[i]=t.query(p[i].t-1)+1;
45         ans=max(ans,f[i]);
46     }
47 //    cout<<T<<endl;
48 //    for (int i=1;i<=n;i++) cout<<f[i]<<' ';cout<<endl;
49     return n-ans<=K;
50 }
51
52 int main()
53 {
56     sort(p+1,p+1+n);
57
58     double L=0,R=1e9;
59     while (R-L>1e-4)
60     {
61         double mid=(L+R)/2.;
62         if (check(mid)) L=mid; else R=mid;
63     }
64     printf(L>1e9-1?"Forever":"%.4lf\n",L);
65     return 0;
66 }
View Code

posted @ 2018-06-24 19:43  Blue233333  阅读(195)  评论(0编辑  收藏  举报