斜率优化(CDQ分治,Splay平衡树):BZOJ 1492: [NOI2007]货币兑换Cash
Description

Input
Output
Sample Input
1 1 1
1 2 2
2 2 3
Sample Output
HINT

测试数据设计使得精度误差不会超过10-7。
对于40%的测试数据,满足N ≤ 10;
对于60%的测试数据,满足N ≤ 1 000;
对于100%的测试数据,满足N ≤ 100 000;
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const double eps=1e-;
const int maxn=;
struct Node{
double a,b,r,x,y,k;
int id;
}d[maxn],t[maxn];
double f[maxn];
int st[maxn],cnt,n;
double Abs(double a){return a>?a:-a;}
double K(int a,int b){
if(Abs(d[a].x-d[b].x)<eps)return 1e20;
return (d[a].y-d[b].y)/(d[a].x-d[b].x);
}
void Solve(int l,int r){
if(l==r){
f[l]=max(f[l],f[l-]);
d[l].y=f[l]/(d[l].r*d[l].a+d[l].b);
d[l].x=d[l].y*d[l].r;
return;
}
int mid=(l+r)>>,t1=l,t2=mid+;
for(int i=l;i<=r;i++){
if(d[i].id<=mid)
t[t1++]=d[i];
else
t[t2++]=d[i];
}
for(int i=l;i<=r;i++)d[i]=t[i];
Solve(l,mid);
cnt=;
for(int i=l;i<=mid;i++){
while(cnt>&&K(i,st[cnt])-K(st[cnt],st[cnt-])>=eps)cnt--;
st[++cnt]=i;
}
int fir=;
for(int i=mid+;i<=r;i++){
while(fir<cnt&&K(st[fir+],st[fir])-d[i].k>=eps)fir++;
f[d[i].id]=max(f[d[i].id],d[st[fir]].x*d[i].a+d[st[fir]].y*d[i].b);
}
Solve(mid+,r);
t1=l;t2=mid+;
for(int i=l;i<=r;i++){
if(t2==r+||(d[t2].x-d[t1].x>=eps||Abs(d[t2].x-d[t1].x)<eps&&d[t2].y-d[t1].y>=eps)&&t1<=mid)
t[i]=d[t1++];
else
t[i]=d[t2++];
}
for(int i=l;i<=r;i++)
d[i]=t[i];
} bool cmp(Node a,Node b){
return a.k>b.k;
}
int main(){
scanf("%d%lf",&n,&f[]);
for(int i=;i<=n;i++){
scanf("%lf%lf%lf",&d[i].a,&d[i].b,&d[i].r);
d[i].k=-d[i].a/d[i].b;
d[i].id=i;
}
sort(d+,d+n+,cmp);
Solve(,n);
printf("%.3lf\n",f[n]);
return ;
}
这里还有Splay。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const double eps=1e-;
const double INF=1e20;
const int maxn=;
int ch[maxn][],fa[maxn],rt,tot,n;
double X[maxn],Y[maxn],lk[maxn],rk[maxn],ans;
double fabs(double x){return (x>)?x:-x;}
void Rotate(int x){
int y=fa[x],g=fa[y],c=ch[y][]==x;
ch[y][c]=ch[x][c^];fa[ch[y][c]]=y;
ch[x][c^]=y;fa[y]=x;fa[x]=g;
if(g)ch[g][ch[g][]==y]=x;
} void Splay(int x,int g=){
for(int y;(y=fa[x])!=g;Rotate(x))
if(fa[y]!=g)Rotate((ch[fa[y]][]==y)==(ch[y][]==x)?y:x);
if(!g)rt=x;
} double Get_K(int j,int k){
if(fabs(X[j]-X[k])<=eps)return INF;
else return (Y[j]-Y[k])/(X[j]-X[k]);
} int Get_Prev(){
int p=ch[rt][],ret=p;
while(p){
if(Get_K(rt,p)+eps>=lk[p])p=ch[p][];
else ret=p,p=ch[p][];
}
return ret;
} int Get_Succ(){
int p=ch[rt][],ret=p;
while(p){
if(Get_K(p,rt)<=rk[p]+eps)p=ch[p][];
else ret=p,p=ch[p][];
}
return ret;
} void Insert(int &r,int pre,int p){
if(r==){r=p;fa[p]=pre;return;}
if(X[p]<=X[r]+eps)Insert(ch[r][],r,p);
else Insert(ch[r][],r,p);
} void Update(int p){
Splay(p);
if (ch[p][]){
int l=Get_Prev();
Splay(l,p);ch[l][]=;
lk[p]=rk[l]=Get_K(p,l);
}
else lk[p]=INF;
if (ch[p][]){
int r=Get_Succ();
Splay(r,p); ch[r][]=;
rk[p]=lk[r]=Get_K(r,p);
}
else rk[p]=-INF;
if (lk[p]<=rk[p]+eps){
rt=ch[p][]; ch[rt][]=ch[p][]; fa[ch[p][]]=rt; fa[rt]=;
rk[rt]=lk[ch[p][]]=Get_K(ch[rt][],rt);
}
} int Get_Pos(double k){
int p=rt;
while(p){
if(lk[p]+eps>=k&&k+eps>=rk[p])break;
if(lk[p]<k+eps)p=ch[p][];
else p=ch[p][];
}
return p;
} double Get_Ans(double a,double b){
int p=Get_Pos(-b/a);
return a*Y[p]+b*X[p];
} int main(){
#ifndef ONLINE_JUDGE
freopen("cash.in","r",stdin);
freopen("cash.out","w",stdout);
#endif
double a,b,rate;
scanf("%d%lf",&n,&ans);
for(int i=;i<=n;i++){
scanf("%lf%lf%lf",&a,&b,&rate);
if(i!=)ans=max(ans,Get_Ans(a,b));
X[i]=ans/(rate*a+b);
Y[i]=X[i]*rate;
Insert(rt,,i);
Update(i);
}
printf("%.3f\n",ans);
return ;
}
斜率优化(CDQ分治,Splay平衡树):BZOJ 1492: [NOI2007]货币兑换Cash的更多相关文章
- BZOJ 1492: [NOI2007]货币兑换Cash( dp + 平衡树 )
dp(i) = max(dp(i-1), x[j]*a[i]+y[j]*b[i]), 0<j<i. x, y表示某天拥有的最多钱去买金券, 金券a和金券b的数量. 然后就很明显了...平衡 ...
- bzoj 1492: [NOI2007]货币兑换Cash
Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下 简称B券).每个持有金券的顾客都有一个自己的帐户.金券的数目可以是一个 ...
- BZOJ.1492.[NOI2007]货币兑换(DP 斜率优化 CDQ分治/Splay)
BZOJ 洛谷 如果某天能够赚钱,那么一定会在这天把手上的金券全卖掉.同样如果某天要买,一定会把所有钱花光. 那么令\(f_i\)表示到第\(i\)天所拥有的最多钱数(此时手上没有任何金券),可以选择 ...
- BZOJ 1492: [NOI2007]货币兑换Cash [CDQ分治 斜率优化DP]
传送门 题意:不想写... 扔链接就跑 好吧我回来了 首先发现每次兑换一定是全部兑换,因为你兑换说明有利可图,是为了后面的某一天两种卷的汇率差别明显而兑换 那么一定拿全利啊,一定比多天的组合好 $f[ ...
- bzoj 1492 [NOI2007]货币兑换Cash(斜率dp+cdq分治)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1492 [题意] 有AB两种货币,每天可以可以付IPi元,买到A券和B券,且A:B= ...
- bzoj 1492: [NOI2007]货币兑换Cash【贪心+斜率优化dp+cdq】
参考:http://www.cnblogs.com/lidaxin/p/5240220.html 虽然splay会方便很多,但是懒得写,于是写了cdq 首先要想到贪心的思路,因为如果在某天买入是能得到 ...
- BZOJ 1492 [NOI2007]货币兑换Cash (CDQ分治/splay 维护凸包)
题目大意:太长了略 splay调了两天一直WA弃疗了 首先,我们可以猜一个贪心,如果买/卖,就一定都买/卖掉,否则不买/卖 反正货币的行情都是已知的,没有任何风险,所以肯定要选择最最最优的方案了 容易 ...
- ●BZOJ 1492 [NOI2007]货币兑换Cash
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1492 题解: 斜率优化DP,CDQ分治 定义$DP[i]$为第i天结束后的最大收益. 由于题 ...
- BZOJ 1492 [NOI2007]货币兑换Cash:斜率优化dp + cdq分治
传送门 题意 初始时你有 $ s $ 元,接下来有 $ n $ 天. 在第 $ i $ 天,A券的价值为 $ A[i] $ ,B券的价值为 $ B[i] $ . 在第 $ i $ 天,你可以进行两种操 ...
随机推荐
- Linux系统下Memcached的安装以及自启动
一.准备工作: 1.下载libevent:http://monkey.org/~provos/libevent/ (由于memcached与客户端的通信是借助libevent来实现的,所以此动作必须在 ...
- partial局部类
局部类型允许我们将一个类.接口或结构分成好几个部分,分别实现在几个不同的.cs文件中. 局部类型适用于以下情况: (1)类型特别大,不宜放在一个文件中实现. (2)一个类型中的一部分代码为自动化工具生 ...
- mvc4+jquerymobile页面加载时无法绑定事件
问题:在view里写js,在页面第一次加载完成后,无法触发事件, 如:按钮click事件,已经在$(function(){ 添加了click });但就是无法触发,必须刷新下才可以. 原因分析: 主 ...
- Activity间的跳转,startActivity与startActivityForResult
JreduCh04 2016-07-30跳转 (由一个画面跳转到另一个画面)两种方法:Intent中 startActivity.startActivityForResult.后者可设置request ...
- PrintWriter 和 BufferedWriter 写入文件.
Ref: should I use PrintWriter to wrap BufferedWriter? The main reason for using PrintWriter is the w ...
- asp.net mvc 通过修改路由规则来实现页面的URL多参数传递
[原文]http://blog.csdn.net/risingsun001/article/details/9068187 修改MVC3中的路由规则 在Global.asax.cs中,修改路由规则 原 ...
- NSDate和NSString的转换及判定是昨天,今天,明天
用于uidate,picker.. +(NSDate*) convertDateFromString:(NSString*)uiDate{ NSDateFormatter *formatter ...
- php输出echo、print、print_r、printf、sprintf、var_dump的区别比较
本篇文章是对php输出echo.print.print_r.printf.sprintf.var_dump的区别进行了详细的分析介绍,需要的朋友参考下 用.net开发已经5年了,最近突然想接触 ...
- c#中设置按钮Button为透明
方法一:代码实现 /// <summary> /// 设置透明按钮样式 /// </summary> private void SetBtnStyle(Button btn) ...
- 2016.7.13final 修饰符使用
final修饰符可以修饰类.变量.函数: 1.被final所修饰的类不能被继承,函数不能被继承,成员变量不能再次被赋值并且被称为常量: 2.被final 修饰的成员变量 .它通常被static所修饰, ...