bzoj1492 斜率优化|cdq分治
1 #include <stdio.h> 2 #include <bitset> 3 #include <string.h> 4 #include <stack> 5 #include <algorithm> 6 #include <iostream> 7 #include <set> 8 #include <map> 9 #include <math.h> 10 #include <queue> 11 #include <complex> 12 using namespace std ; 13 typedef long long ll ; 14 typedef long double ld ; 15 typedef unsigned long long ull ; 16 #ifdef _WIN32 17 #define LLD "%I64d" 18 #else 19 #define LLD "%lld" 20 #endif 21 #define pi (acos(-1.0)) 22 #define fi first 23 #define se second 24 #define lson (o<<1),l,mid 25 #define rson (o<<1|1),mid+1,r 26 #define MP make_pair 27 #define sqr(x) ((x)*(x)) 28 #define ALL(v) (v).begin(),(v).end() 29 #define showtime fprintf(stderr,"time = %.15f\n",clock() / (double)CLOCKS_PER_SEC) 30 const double eps = 1e-8; 31 const int inf = 0x3f3f3f3f ; 32 const ll INF = (ll)4e18 ; 33 const int MOD=(int)1e9+7,BAS=257,invBAS=70038911; 34 int sign(double x){return x<-eps?-1:x>eps;} 35 36 const int M = 110000 ; 37 struct Point { 38 int id ; 39 double a,b,rate,x,y ; 40 inline void minus (Point t) { 41 x-=t.x ; y-=t.y ; 42 } 43 inline double mul (Point t) { 44 return x*t.y-y*t.x ; 45 } 46 inline bool operator < (const Point &t) { 47 if (sign(x-t.x)==0) return y>t.y ; 48 return x<t.x ; 49 } 50 } p[M] , c[M] ; 51 int n , st[M] , sz ; 52 double money[M] ; 53 54 double slope (Point e,Point t,Point g) { 55 e.minus(g) ; t.minus(g) ; 56 return sign(t.mul(e))<=0 ; 57 } 58 59 double get (int i,int j) { 60 return p[i].x*p[j].b+p[i].y*p[j].a ; 61 } 62 63 void cdq (int l,int r) { 64 if (l == r) { 65 money[l] = max(money[l-1],money[l]) ; 66 p[l].x = money[l]/(p[l].a*p[l].rate+p[l].b) ; 67 p[l].y = p[l].x*p[l].rate ; 68 return ; 69 } 70 int mid = l+r>>1 ; 71 for (int i=l,j=0,k=1; i<=r ; i ++) 72 if (p[i].id<=mid) c[l+j++] = p[i] ; 73 else c[mid+k++] = p[i] ; 74 memcpy (p+l,c+l,sizeof(Point)*(r-l+1)) ; 75 cdq (l,mid) ; 76 sz = 0 ; 77 for (int i=l ; i<=mid ; i++) { 78 if (sz && sign(p[st[sz-1]].x-p[i].x)==0) continue ; 79 while (sz>1&&slope(p[st[sz-2]],p[st[sz-1]],p[i]))sz --; 80 st[sz++] = i ; 81 } 82 for (int i=mid+1 ; i<=r ; i++) { 83 while (sz>1 && sign(get(st[sz-2],i)-get(st[sz-1],i))>0) sz -- ; 84 money[p[i].id] = max (money[p[i].id] , get(st[sz-1],i)) ; 85 } 86 cdq (mid+1,r) ; 87 int e=l , t=mid+1 ; 88 for (int i=l ; i<=r ; i++) 89 if (e<=mid && (t>r || p[e]<p[t])) c[i] = p[e++] ; 90 else c[i] = p[t++] ; 91 memcpy(p+l,c+l,sizeof(Point)*(r-l+1)) ; 92 } 93 94 bool cmp (const Point &e , const Point &t) { return e.b*t.a>t.b*e.a ; } 95 96 int main () { 97 scanf ("%d%lf" , &n , money) ; 98 for (int i=0 ; i<n ; i ++) { 99 scanf ("%lf%lf%lf" , &p[i].a,&p[i].b,&p[i].rate); 100 p[i].id = i ; 101 } 102 sort (p,p+n,cmp) ; 103 cdq (0,n-1) ; 104 printf ("%.3f\n" , money[n-1]) ; 105 return 0 ; 106 }