题意:

上一篇

题解:

方程还是那个方程f[i]=A[i] * X[j] + B[i] * Y[j]。

化简为Y[i]=(-A[i]/B[i]) * X[i] + f[i]/B[i]这一坨;

既然这个斜率不单调,那排个序让它单调不即可了;

排序之后的问题就是,在i前面更新i的点不一定能够更新i。而应该用来更新i的点说不定还在i的后面;

那么这时候就是用CDQ分治解决。

经典的四步先贴上来:

1.将操作依照时间划分为两个子区间。

2.递归处理左区间的改动与询问。

3.用左区间的改动处理右区间的询问;

4.递归处理右区间的改动与询问;

光这么四句话肯定没用,以下是详细的;

动态规划中对f[i]的更新相当于是查询,而用f[i]来更新别人则相当于是一次改动;

那么在将全部的点按斜率排序之后,进行一个分治的solve(1,n),然后按四步走;

1.划分区间:

这里的时间就是天数,仅仅须要取一个mid然后用mid把点分成两堆。

注意这里划分了以后。两个区间仍按斜率有序。而且左区间的所有时间都小于右区间的所有时间;

2.递归处理左区间:

递归下去要有一个边界,这里的边界显然就是l==r的时候;

这时这个结点前面的结点都已经对它更新了;

所以它在更新一下f[i-1]就是终于的f[i]。顺便计算出X[i]Y[i]的值;

然后每层递归结束时要按X[i]排序(为了维护凸包方便)(这种递归结构下用归并的线性显然比快拍要好);

3.用左区间改动右区间:

左区间已经按X[i]排序完毕,能够扫一遍求出凸包;

右区间如今还是按斜率排序。直接上斜率优化;

这时候右区间的全部点已经被左区间的点处理完了;

4.递归处理右区间:

被左区间处理了的点还要被右区间在它前面的点处理。所以再递归搞一下。

然后就结束了。f[n]就是答案。

这些操作全都是线性复杂度的,而一共递归有logn层。复杂度为O(nlogn);

排完序之后的下标不是时间。

。。sort写错的去看眼科大夫。

。。

代码2k+,时间1232ms;

竟然没有平衡树跑得快,可是代码上的确是省了不少。

顺便一提。bz AC50题留念(笑);

代码:

#include<math.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 110000
#define which(x) (tr[tr[x].fa].ch[1]==x)
const double INF = 1e100;
const double EPS = 1e-8;
using namespace std;
struct node
{
double x, y, slope;
int no;
}a[N], temp[N];
double f[N], A[N], B[N], R[N];
int st[N];
int cmp(node a, node b)
{
return a.slope < b.slope;
}
double slope(int x, int y)
{
if (fabs(a[x].x - a[y].x) < EPS)
return a[x].y < a[y].y ? INF : -INF;
else
return (a[x].y - a[y].y) / (a[x].x - a[y].x);
}
void merge(int l, int r)
{
memcpy(temp + l, a + l, sizeof(node)*(r - l + 1));
int mid = (l + r) >> 1, i, j, k;
for (k = l, i = l, j = mid + 1; k <= r; k++)
{
if (i <= mid&&j <= r)
a[k] = temp[i].x < temp[j].x ? temp[i++] : temp[j++];
else
a[k] = (i == mid + 1 ? temp[j++] : temp[i++]);
}
}
void slove(int l, int r)
{
if (l == r)
{
f[l] = max(f[l], f[l - 1]);
a[l].y = f[l] / (A[l] * R[l] + B[l]);
a[l].x = R[l] * a[l].y;
}
else
{
int mid = (l + r) >> 1, i, j, k, top;
for (i = l, j = l, k = mid + 1; i <= r; i++)
if (a[i].no <= mid)
temp[j++] = a[i];
else
temp[k++] = a[i];
memcpy(a + l, temp + l, sizeof(node)*(r - l + 1));
slove(l, mid);
st[top = 1] = l;
for (i = l + 1; i <= mid; i++)
{
while (top >= 2 && slope(st[top - 1], st[top]) < slope(st[top], i))
top--;
st[++top] = i;
}
for (i = mid + 1; i <= r; i++)
{
while (top >= 2 && slope(st[top - 1], st[top]) < a[i].slope)
top--;
f[a[i].no] = max(f[a[i].no], A[a[i].no] * a[st[top]].x + B[a[i].no] * a[st[top]].y);
}
slove(mid + 1, r);
merge(l, r);
}
}
int main()
{
int n, i, j, k;
double ans;
scanf("%d%lf", &n, &f[1]);
for (i = 1; i <= n; i++)
scanf("%lf%lf%lf", A + i, B + i, R + i),
a[i].slope = -A[i] / B[i],
a[i].no = i;
sort(a + 1, a + n + 1, cmp);
slove(1, n);
printf("%.3lf", f[n]);
return 0;
}

bzoj-1492 货币兑换Cash (2)——CDQ分治的更多相关文章

  1. 【BZOJ】1492: [NOI2007]货币兑换Cash(cdq分治)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1492 蒟蒻来学学cdq神算法啊.. 详见论文 陈丹琦<从<Cash>谈一类分治算法 ...

  2. BZOJ 1492 货币兑换 Cash CDQ分治

    这题n2算法就是一个维护上凸包的过程. 也可以用CDQ分治做. 我的CDQ分治做法和网上的不太一样,用左边的点建立一个凸包,右边的点在上面二分. 好处是思路清晰,避免了凸包的插入删除,坏处是多了一个l ...

  3. 1492: [NOI2007]货币兑换Cash【CDQ分治】

    1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 4166  Solved: 1736[Submit][Sta ...

  4. BZOJ 1492 货币兑换Cash

    http://www.lydsy.com/JudgeOnline/problem.php?id=1492 思路: 问题转变为维护一个凸包,每次转移都找凸包上的点,并更新凸壳 可以用splay维护,或者 ...

  5. bzoj1492 [NOI2007]货币兑换Cash【cdq分治】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1492 推荐博客:http://www.cnblogs.com/zig-zag/archive ...

  6. 【BZOJ1492】货币兑换Cash(CDQ分治)

    题意: 小 Y 最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A 纪 念券(以下简称 A 券)和 B 纪念券(以下简称 B 券).每个持有金券的顾客都有 一个自己的帐户.金券的数目可以是一 ...

  7. Luogu 3810 & BZOJ 3262 陌上花开/三维偏序 | CDQ分治

    Luogu 3810 & BZOJ 3263 陌上花开/三维偏序 | CDQ分治 题面 \(n\)个元素,每个元素有三个值:\(a_i\), \(b_i\) 和 \(c_i\).定义一个元素的 ...

  8. BZOJ 1492 货币兑换 cdq分治或平衡树维护凸包

    题意:链接 方法:cdq分治或平衡树维护凸包 解析: 这道题我拒绝写平衡树的题解,我仅仅想说splay不要写挂,insert边界条件不要忘.del点的时候不要脑抽d错.有想写平衡树的去看140142或 ...

  9. BZOJ 1492 货币兑换

    Description Input 第一行两个正整数\(N,S\),分别表示小Y 能预知的天数以及初始时拥有的钱数. 接下来\(N\)行,第\(K\)行三个实数\(A_{K},B_{K},Rate_{ ...

随机推荐

  1. [CF226E]Noble Knight's Path

    [CF226E]Noble Knight's Path 题目大意: 一棵\(n(n\le10^5)\)个结点的树,初始时所有结点都是白色.\(m(m\le10^5)\)次操作,操作包含以下两种: 将点 ...

  2. 【HDU】6410:序列期望

    序列期望 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submis ...

  3. bzoj 1009: [HNOI2008]GT考试 -- KMP+矩阵

    1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MB Description 阿申准备报名参加GT考试,准考证号为N位数X1X2.. ...

  4. 04-RocketMQ入门及其使用(一)

    视频开始主要介绍数据库逻辑以及分表相关的设计. 关键的数据库读写分析操作---

  5. Java获取Access数据库连接单例简单实例

    Java在连接Access数据库时比较方便,不用导入第三方的jar包,jdk中内置的odbc可以完成Access数据库的访问,需要注意的是,我们首先要配置Access数据库的数据源,还要区分x86和x ...

  6. iOS开发系列——内购、GameCenter、iCloud、Passbook系统服务开发汇总

    社交 Social 现在很多应用都内置“社交分享”功能,可以将看到的新闻.博客.广告等内容分享到微博.微信.QQ.空间等,其实从iOS6.0开始苹果官方就内置了Social.framework专门来实 ...

  7. 阻止a标签跳转

       一.在html中 1. <a href="javascript:;"></a> 2. <a href="###">&l ...

  8. Ubuntu中升极下载4.2内核

    http://tech.hexun.com/2015-09-11/179027013.html 从这段话中所表达出的意思可以了解,Linux Kernel 4.3版本已经开始进行,Linus Torv ...

  9. mysql localhost登录和tcp/ip登录 strace

    http://blog.itpub.net/15480802/viewspace-1755100/

  10. security with restful

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...