您的位置:首页 > 其它

[BZOJ 1492]货币兑换Cash

2016-02-22 19:06 253 查看
维护凸壳

CDQ

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define maxn 100010
using namespace std;

const double eps = 1e-8;

const int inf = 0x7fffffff;

struct opt{
	double q, a, b, rate, k;
	int pos;
}q[maxn], nq[maxn];

int Filter(double x){
	return x > eps ? 1 : (x < -eps ? -1 : 0);
}

struct Point{
	double x, y;
	bool operator<(const Point& k)const{
		return (Filter(x - k.x) < 0) || 
		(Filter(x - k.x) == 0 && Filter(y - k.y) < 0);
	}
}p[maxn], np[maxn];

double f[maxn];
int st[maxn], n, m;
#define K getk
double K(int i, int j){
	if (i == 0) return -inf;
    if (j == 0) return inf;
    if (Filter(p[i].x-p[j].x) == 0) return -inf;
	return (p[i].y - p[j].y) / (p[i].x - p[j].x);
}

void solve(int l, int r){
	if(l == r){
		f[l] = max(f[l - 1], f[l]);
		p[l].x = f[l] / (q[l].a * q[l].rate + q[l].b) * q[l].rate;
		p[l].y = f[l] / (q[l].a * q[l].rate + q[l].b);
		return;
	}
    int mid = l + r >> 1, l1 = l, l2 = mid + 1;
    for(int i = l; i <= r; i ++)
		if(q[i].pos <= mid)nq[l1 ++] = q[i];
		else nq[l2 ++] = q[i];
	memcpy(q + l, nq + l, sizeof (q[0]) * (r - l + 1));
	
    solve(l, mid);
    
	int top = 0;
	
	for(int i = l; i <= mid; i ++){
		while(top >= 2 && Filter(K(i, st[top]) - K(st[top], st[top - 1])) >= 0)
			top --;
		st[++ top] = i;
	}
	
	int j = 1;
	for(int i = r; i >= mid + 1; i --){
		while(j < top && Filter(q[i].k - K(st[j], st[j + 1])) <= 0)
			j ++;
		f[q[i].pos] = max(f[q[i].pos], p[st[j]].x * q[i].a + p[st[j]].y * q[i].b);
	}
	
	solve(mid + 1, r);
	l1 = l, l2 = mid + 1;
	for(int i = l; i <= r; i ++){
		if((p[l1] < p[l2] || l2 > r) && l1 <= mid)
			np[i] = p[l1 ++];
		else np[i] = p[l2 ++];
	}
	memcpy(p + l, np + l, sizeof (p[0]) * (r - l + 1));
}

bool cmp(const opt& a, const opt& b){
	return a.k < b.k;
}

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