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 }

 

posted @ 2016-07-29 10:26  92度的苍蓝  阅读(649)  评论(0编辑  收藏  举报
http://images.cnblogs.com/cnblogs_com/Running-Time/724426/o_b74124f376fc157f352acc88.jpg