BZOJ 1492 货币兑换 cdq分治或平衡树维护凸包
题意:链接
方法:cdq分治或平衡树维护凸包
解析:
这道题我拒绝写平衡树的题解,我仅仅想说splay不要写挂,insert边界条件不要忘。del点的时候不要脑抽d错。有想写平衡树的去看140142或者留言我。
首先这道题能推出个表达式
f[i]代表第i天最大收益。
xx[i]表示将第i天的钱都买A的数量
yy[i]表示将第i天的钱都买B的数量
所以f[i]=max(f[i−1],p[i].a∗xx[j]+p[i].b∗yy[j])j<i
所以我们要维护这个n^2的递推式
又知道f[i]是由小于i的j更新的,
但方程要进一步写一下
yy[i]=(-p[i].a/p[i].b)*xx[i]+f[i]/p[i].b
所以我们要得到最大截距所以能够依照斜率递减维护一个凸包来找某一确定直线与这个凸包截得的最大截距,也就是斜率第一个小于等于它的某个凸包上的点。
之后的部分就是採用cdq维护或者平衡树
平衡树真是一个噩梦
代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 100010
#define eps 1e-9
#define INF 0x7fffffff
using namespace std;
typedef long long ll;
int n;
double f[N];
int stack[N];
struct node
{
double x,y,a,b,rate,k;
int w;
}p[N],t[N];
int cmp(node a,node b)
{
return a.k>b.k;
}
double getk(int a,int b)
{
if(!b)return -INF;
if(fabs(p[a].x-p[b].x)<eps)return INF;
return (p[b].y-p[a].y)/(p[b].x-p[a].x);
}
void solve(int l,int r)
{
if(l==r)
{
f[l]=max(f[l-1],f[l]);
p[l].y=f[l]/(p[l].a*p[l].rate+p[l].b);
p[l].x=p[l].rate*p[l].y;
return;
}
int mid=(l+r)>>1;
int l1=l,l2=mid+1,pt=1;
for(int i=l;i<=r;i++)
{
if(p[i].w<=mid)t[l1++]=p[i];
else t[l2++]=p[i];
}
for(int i=l;i<=r;i++)p[i]=t[i];
solve(l,mid);
int top=0;
for(int i=l;i<=mid;i++)
{
while(top>1&&getk(stack[top-1],stack[top])<=getk(stack[top],i))top--;
stack[++top]=i;
}
stack[++top]=0;
for(int i=mid+1;i<=r;i++)
{
while(pt<top&&getk(stack[pt],stack[pt+1])>p[i].k)pt++;
f[p[i].w]=max(f[p[i].w],p[stack[pt]].x*p[i].a+p[stack[pt]].y*p[i].b);
}
solve(mid+1,r);
l1=l,l2=mid+1;
for(int i=l;i<=r;i++)
if(((p[l1].x<p[l2].x||(fabs(p[l1].x-p[l2].x)<eps&&p[l1].y<p[l2].y))||l2>r)&&l1<=mid)t[i]=p[l1++];
else t[i]=p[l2++];
for(int i=l;i<=r;i++)p[i]=t[i];
}
int main()
{
scanf("%d%lf",&n,&f[0]);
for(int i=1;i<=n;i++)
{
scanf("%lf%lf%lf",&p[i].a,&p[i].b,&p[i].rate);
p[i].k=-p[i].a/p[i].b;
p[i].w=i;
}
sort(p+1,p+1+n,cmp);
solve(1,n);
printf("%.3lf\n",f[n]);
}
BZOJ 1492 货币兑换 cdq分治或平衡树维护凸包的更多相关文章
- 【BZOJ1492】【Luogu P4027】 [NOI2007]货币兑换 CDQ分治,平衡树,动态凸包
斜率在转移顺序下不满足单调性的斜率优化\(DP\),用动态凸包来维护.送命题. 简化版题意:每次在凸包上插入一个点,以及求一条斜率为\(K\)的直线与当前凸包的交点.思路简单实现困难. \(P.s\) ...
- [BZOJ 3456]城市规划(cdq分治+FFT)
[BZOJ 3456]城市规划(cdq分治+FFT) 题面 求有标号n个点无向连通图数目. 分析 设\(f(i)\)表示\(i\)个点组成的无向连通图数量,\(g(i)\)表示\(i\)个点的图的数量 ...
- [BZOJ 2989]数列(CDQ 分治+曼哈顿距离与切比雪夫距离的转化)
[BZOJ 2989]数列(CDQ 分治) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]| ...
- BZOJ 1492 货币兑换 Cash CDQ分治
这题n2算法就是一个维护上凸包的过程. 也可以用CDQ分治做. 我的CDQ分治做法和网上的不太一样,用左边的点建立一个凸包,右边的点在上面二分. 好处是思路清晰,避免了凸包的插入删除,坏处是多了一个l ...
- BZOJ 1492 货币兑换
Description Input 第一行两个正整数\(N,S\),分别表示小Y 能预知的天数以及初始时拥有的钱数. 接下来\(N\)行,第\(K\)行三个实数\(A_{K},B_{K},Rate_{ ...
- BZOJ 1492 货币兑换Cash
http://www.lydsy.com/JudgeOnline/problem.php?id=1492 思路: 问题转变为维护一个凸包,每次转移都找凸包上的点,并更新凸壳 可以用splay维护,或者 ...
- [NOI2007]货币兑换 cdq分治,斜率优化
[NOI2007]货币兑换 LG传送门 妥妥的\(n \log n\)cdq做法. 这题用cdq分治也可以\(n \log n\)但是在洛谷上竟然比一些优秀的splay跑得慢真是见了鬼了看来还是人丑常 ...
- 【LOJ2586】【APIO2018】选圆圈 CDQ分治 扫描线 平衡树
题目描述 在平面上,有 \(n\) 个圆,记为 \(c_1,c_2,\ldots,c_n\) .我们尝试对这些圆运行这个算法: 找到这些圆中半径最大的.如果有多个半径最大的圆,选择编号最小的.记为 \ ...
- bzoj 4237 稻草人 - CDQ分治 - 单调栈
题目传送门 传送点I 传送点II 题目大意 平面上有$n$个点.问存在多少个矩形使得只有左下角和右上角有点. 考虑枚举左下角这个点.然后看一下是个什么情况: 嗯对,是个单调栈.但不可能暴力去求每个点右 ...
随机推荐
- centos语言设置
. echo $LANG可以查看当前使用的系统语言 . 在终端输入 locale命令,如有zh cn 表示已经安装了中文 . 安装中文语言包yum groupinstall chinese-suppo ...
- An problem about date 根据年月日计算 星期几
/W = (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7(1.2月需要看作上一年的13.14月) #include<stdio.h> #include& ...
- ASP.NET MVC5 之 AspNetUsers 表增加字段
MVC5 执行数据库迁移时,会生成一些默认的数据表,但是在实际的工作中.若用到的时候,难免要增添一些字段. 1.AspNetUsers 增加字段 A.打开MVC中的 IdentityModels.cs ...
- [转]mysql视图学习总结
转自:http://www.cnblogs.com/wangtao_20/archive/2011/02/24/1964276.html 一.使用视图的理由是什么?1.安全性.一般是这样做的:创建一个 ...
- [转]linux之cut命令的用法
转自:http://www.jb51.net/article/41872.htm cut是一个选取命令,就是将一段数据经过分析,取出我们想要的.一般来说,选取信息通常是针对“行”来进行分析的,并不是整 ...
- ios的认识
刚进了ios兴趣班,第一次使用苹果电脑,因为苹果电脑和windows电脑使用的区别很大.所以老师教我们苹果电脑的基本使用,以及关于苹果产品的一些认识.我听得热血沸腾,对苹果开发越来越感兴趣,相信下次上 ...
- TextOut与DrawText的区别
BOOL TextOut( HDC hdc, // 句柄 int nXStart, // 字符串的开始位置 x坐标 int nYStart, // 字符串的开始位置 y坐标 LPCTSTR lpStr ...
- node(koa)微信公众号接口认证
使用微信测试号, 花生壳内网穿透 需要注意 token 两边都是自定义, 需要保持一致, const Koa = require('koa') const sha1 = require('sha1') ...
- 移动web——bootstrap如何修改原组件
基本介绍 1.bootstrap提供了丰富的组件,但是有时候我们不仅要删除不必要的标签,还需要修改里面的样式 2.我们建议若是修改样式那么最好将源样式从css中拷贝出来,名字换掉,然后修改具体样式,这 ...
- html5——背景
背景大小 background-size: % %;//宽 高 background-size: 100px 100px;//宽 高 background-size: cover;//覆盖,图片会完全 ...