BZOJ 1492 Cash(CDQ分治论文题)

CDQ分治论文题

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#include<ctime>
#define eps 1e-9
#define LL long long
#define pii pair<int, int>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

const int maxn = 100000 + 1000;
int n;
double ans[maxn];
struct Point {
	double a, b, r;
	double x, y, k;
	int id;
	bool operator < (const Point& A) const {
		return x < A.x;
	}
} p[maxn], t[maxn];
int S[maxn];
double getK(int a, int b) {
	if(!b) return 1e-20;
	if(fabs(p[a].x-p[b].x) < eps) return 1e20;
	return (p[b].y-p[a].y) / (p[b].x-p[a].x);
}
bool cmp(const Point A, const Point B) {
	return A.k > B.k;
}
void CDQ(int L, int R) {
	if(L == R) {
		ans[L] = max(ans[L], ans[L-1]);
		p[L].y = ans[L]/(p[L].r*p[L].a+p[L].b);
		p[L].x = p[L].y*p[L].r;
		return;
	}
	int mid = (L+R) >> 1;
	int l1 = L, l2 = mid + 1;
	for(int i = L; i <= R; i++) {
		if(p[i].id > mid) t[l2++] = p[i];
		else t[l1++] = p[i];
	}
	for(int i = L; i <= R; i++) p[i] = t[i];
	CDQ(L, mid);
	int top = 0, pos = 1;
	for(int i = L; i <= mid; i++) {
		while(top>1 && getK(S[top-1], S[top])<getK(S[top-1], i)+eps)
			top--;
		S[++top] = i;
	}
	for(int i = mid+1; i <= R; i++) {
		while(pos<top && getK(S[pos], S[pos+1])+eps>p[i].k) pos++;
		ans[p[i].id] = max(ans[p[i].id], p[i].a*p[S[pos]].x+p[i].b*p[S[pos]].y);
	}
	CDQ(mid+1, R);
	merge(p+L, p+mid+1, p+mid+1, p+R+1, t+L);
	for(int i = L; i <= R; i++) p[i] = t[i];
} 

int main() {
    //freopen("input.txt", "r", stdin);
	scanf("%d%lf", &n, &ans[0]);
	for(int i = 1; i <= n; i++) {
		scanf("%lf%lf%lf", &p[i].a, &p[i].b, &p[i].r);
		p[i].k = -p[i].a/p[i].b;
		p[i].id = i;
	}
	sort(p+1, p+n+1, cmp);
	CDQ(1, n);
	printf("%.3lf", ans[n]);
    return 0;
}

















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值