您的位置:首页 > 其它

bzoj1492 斜率优化|cdq分治

2016-07-29 10:26 417 查看
#include <stdio.h>
#include <bitset>
#include <string.h>
#include <stack>
#include <algorithm>
#include <iostream>
#include <set>
#include <map>
#include <math.h>
#include <queue>
#include <complex>
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef unsigned long long ull ;
#ifdef _WIN32
#define LLD "%I64d"
#else
#define LLD "%lld"
#endif
#define pi (acos(-1.0))
#define fi first
#define se second
#define lson (o<<1),l,mid
#define rson (o<<1|1),mid+1,r
#define MP make_pair
#define sqr(x) ((x)*(x))
#define ALL(v) (v).begin(),(v).end()
#define showtime fprintf(stderr,"time = %.15f\n",clock() / (double)CLOCKS_PER_SEC)
const double eps = 1e-8;
const int inf = 0x3f3f3f3f ;
const ll INF = (ll)4e18 ;
const int MOD=(int)1e9+7,BAS=257,invBAS=70038911;
int sign(double x){return x<-eps?-1:x>eps;}

const int M = 110000 ;
struct Point {
int id ;
double a,b,rate,x,y ;
inline void minus (Point t) {
x-=t.x ; y-=t.y ;
}
inline double mul (Point t) {
return x*t.y-y*t.x ;
}
inline bool operator < (const Point &t) {
if (sign(x-t.x)==0) return y>t.y ;
return x<t.x ;
}
} p[M] , c[M] ;
int n , st[M] , sz ;
double money[M] ;

double slope (Point e,Point t,Point g) {
e.minus(g) ; t.minus(g) ;
return sign(t.mul(e))<=0 ;
}

double get (int i,int j) {
return p[i].x*p[j].b+p[i].y*p[j].a ;
}

void cdq (int l,int r) {
if (l == r) {
money[l] = max(money[l-1],money[l]) ;
p[l].x = money[l]/(p[l].a*p[l].rate+p[l].b) ;
p[l].y = p[l].x*p[l].rate ;
return ;
}
int mid = l+r>>1 ;
for (int i=l,j=0,k=1; i<=r ; i ++)
if (p[i].id<=mid) c[l+j++] = p[i] ;
else c[mid+k++] = p[i] ;
memcpy (p+l,c+l,sizeof(Point)*(r-l+1)) ;
cdq (l,mid) ;
sz = 0 ;
for (int i=l ; i<=mid ; i++) {
if (sz && sign(p[st[sz-1]].x-p[i].x)==0) continue ;
while (sz>1&&slope(p[st[sz-2]],p[st[sz-1]],p[i]))sz --;
st[sz++] = i ;
}
for (int i=mid+1 ; i<=r ; i++) {
while (sz>1 && sign(get(st[sz-2],i)-get(st[sz-1],i))>0) sz -- ;
money[p[i].id] = max (money[p[i].id] , get(st[sz-1],i)) ;
}
cdq (mid+1,r) ;
int e=l , t=mid+1 ;
for (int i=l ; i<=r ; i++)
if (e<=mid && (t>r || p[e]<p[t])) c[i] = p[e++] ;
else c[i] = p[t++] ;
memcpy(p+l,c+l,sizeof(Point)*(r-l+1)) ;
}

bool cmp (const Point &e , const Point &t) { return e.b*t.a>t.b*e.a ; }

int main () {
scanf ("%d%lf" , &n , money) ;
for (int i=0 ; i<n ; i ++) {
scanf ("%lf%lf%lf" , &p[i].a,&p[i].b,&p[i].rate);
p[i].id = i ;
}
sort (p,p+n,cmp) ;
cdq (0,n-1) ;
printf ("%.3f\n" , money[n-1]) ;
return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: