BZOJ4700 适者(贪心+cdq分治+斜率优化)
首先考虑怎么安排攻击顺序。显然如果攻击了某台兵器就应该一直连续攻击直到将其破坏,破坏所需时间可以直接算出来,设其为b。假设确定了某个破坏顺序,如果交换相邻两个兵器,显然不会对其他兵器造成影响,两种顺序的代价则分别为a1(b1-1)+a2(b1+b2-1)和a1(b1+b2-1)+a2(b2-1),那么当a2b1<a1b2时先破坏1较优。于是按b/a从小到大排序。
然后考虑怎么秒杀。如果只能秒杀一个显然直接枚举即可。假设已确定要秒杀的是第i个,则需要找到j>i最小化Σax(Bx-1)-ai(Bi-1)-aj(Bj-1)-(An-Ai)bi-(An-Aj)bj+ajbi (Ax=Σay Bx=Σby(y=1~x))(注意是护甲值<=0时被破坏,题面错了,开始这个式子半天没过样例还以为锅了)。设ci=ai(Bi-1)+(An-Ai)bi,则要最小化ajbi-ci-cj。考虑类似斜率优化的东西,若i固定时j比k优,则ajbi-cj<akbi-ck,即bi(aj-ak)<cj-ck,若aj>ak则bi<(cj-ck)/(aj-ak)。这里的a和b都没有单调性,还要保证i编号小于j,那么同样用斜率优化dp的思路,cdq分治,对左边按b从大到小排序,右边按a小到大排序造出上凸壳。只会log^2。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 300010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,m,q[N];
ll ans,tot,c[N];
struct data{int x,y;ll z;
}a[N],b[N];
bool cmp(const data&a,const data&b)
{
return b.x*a.y<a.x*b.y;
}
bool cmp2(const data&a,const data&b)
{
return a.y>b.y;
}
bool cmp3(const data&a,const data&b)
{
return a.x<b.x;
}
ll calc(int x,int y)
{
return tot-a[x].z-a[y].z+a[y].x*a[x].y;
}
double slope(int i,int j)
{
return (double)(a[j].z-a[i].z)/(a[j].x-a[i].x);
}
void solve(int l,int r)
{
if (l>=r) return;
int mid=l+r>>;
solve(l,mid);
solve(mid+,r);
sort(a+l,a+mid+,cmp2);
sort(a+mid+,a+r+,cmp3);
int head=,tail=;
for (int i=mid+;i<=r;i++)
{
while (head<tail&&slope(q[tail-],q[tail])<slope(q[tail],i)) tail--;
q[++tail]=i;
}
for (int i=l;i<=mid;i++)
{
while (head<tail&&slope(q[head],q[head+])>a[i].y) head++;
ans=min(ans,calc(i,q[head]));
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4700.in","r",stdin);
freopen("bzoj4700.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read(),m=read();
ll A=,B=;
for (int i=;i<=n;i++) (A+=a[i].x=read()),a[i].y=(read()-)/m+;
sort(a+,a+n+,cmp);
for (int i=;i<=n;i++)
{
A-=a[i].x,B+=a[i].y;
a[i].z=a[i].x*(B-)+A*a[i].y;
tot+=a[i].x*(B-);
}
ans=tot;
solve(,n);
cout<<ans;
return ;
}
BZOJ4700 适者(贪心+cdq分治+斜率优化)的更多相关文章
- 【uoj#244】[UER #7]短路 CDQ分治+斜率优化dp
题目描述 给出 $(2n+1)\times (2n+1)$ 个点,点 $(i,j)$ 的权值为 $a[max(|i-n-1|,|j-n-1|)]$ ,找一条从 $(1,1)$ 走到 $(2n+1,2n ...
- BZOJ1492:[NOI2007]货币兑换 (CDQ分治+斜率优化DP | splay动态维护凸包)
BZOJ1492:[NOI2007]货币兑换 题目传送门 [问题描述] 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和B纪念券(以下简称B券).每个持有金券的 ...
- [BZOJ1492] [NOI2007] 货币兑换Cash(cdq分治+斜率优化)
[BZOJ1492] [NOI2007] 货币兑换Cash(cdq分治+斜率优化) 题面 分析 dp方程推导 显然,必然存在一种最优的买卖方案满足:每次买进操作使用完所有的人民币:每次卖出操作卖出所有 ...
- BZOJ 1492: [NOI2007]货币兑换Cash [CDQ分治 斜率优化DP]
传送门 题意:不想写... 扔链接就跑 好吧我回来了 首先发现每次兑换一定是全部兑换,因为你兑换说明有利可图,是为了后面的某一天两种卷的汇率差别明显而兑换 那么一定拿全利啊,一定比多天的组合好 $f[ ...
- bzoj1492[NOI2007]货币兑换Cash cdq分治+斜率优化dp
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 5541 Solved: 2228[Submit][Sta ...
- bzoj3672/luogu2305 购票 (运用点分治思想的树上cdq分治+斜率优化dp)
我们都做过一道题(?)货币兑换,是用cdq分治来解决不单调的斜率优化 现在它放到了树上.. 总之先写下来dp方程,$f[i]=min\{f[j]+(dis[i]-dis[j])*p[i]+q[i]\} ...
- BZOJ 3963 HDU3842 [WF2011]MachineWorks cdq分治 斜率优化 dp
http://acm.hdu.edu.cn/showproblem.php?pid=3842 写的check函数里写的<但是应该是<=,调了一下午,我是个zz. 就是普通的斜率优化因为有两 ...
- 【BZOJ3963】[WF2011]MachineWorks cdq分治+斜率优化
[BZOJ3963][WF2011]MachineWorks Description 你是任意性复杂机器公司(Arbitrarily Complex Machines, ACM)的经理,公司使用更加先 ...
- BZOJ 3963: [WF2011]MachineWorks [CDQ分治 斜率优化DP]
传送门 当然了WF的题uva hdu上也有 你的公司获得了一个厂房N天的使用权和一笔启动资金,你打算在这N天里租借机器进行生产来获得收益.可以租借的机器有M台.每台机器有四个参数D,P,R,G.你可以 ...
随机推荐
- QtChart 初体验
早就知道 Qt 5.7 中引入了 QtChart 模块.一直没时间试用.周末正好空闲,就简单的试了试 QtChart.QtChart 学起来还是挺简单的,基于 Qt Graphics View Fra ...
- CF 1033 C. Permutation Game
C. Permutation Game http://codeforces.com/contest/1033/problem/C 题意: 一个排列,每个位置i走到的位置j满足:a[j]>a[i] ...
- springboot+websocket+sockjs进行消息推送【基于STOMP协议】
springboot+websocket+sockjs进行消息推送[基于STOMP协议] WebSocket是在HTML5基础上单个TCP连接上进行全双工通讯的协议,只要浏览器和服务器进行一次握手,就 ...
- Objective-C NSString基本使用 类方法 self关键字
NSString基本使用 #import <Foundation/Foundation.h> int main() { //最简单的创建字符串的方式 NSString *str = @&q ...
- Java开发工程师(Web方向) - 03.数据库开发 - 第2章.数据库连接池
第2章--数据库连接池 数据库连接池 一般而言,在实际开发中,往往不是直接使用JDBC访问后端数据库,而是使用数据库连接池的机制去管理数据库连接,来实现对后端数据库的访问. 建立Java应用程序到后端 ...
- python 终极篇 --- form组件 与 modelForm
form组件 ...
- 什么是Spark
什么是Spark Apache Spark是一个开源集群运算框架, 相对于Hadoop的MapReduce会在运行完工作后将中介数据存放到磁盘中,Spark使用了存储器内运算技术,能在数据尚未写入硬盘 ...
- 【转载】android 常用开源框架
对于Android初学者以及对于我们菜鸟,这些大神们开发的轻量级框架非常有用(更别说开源的了). 下面转载这10个框架的介绍:(按顺序来吧没有什么排名). 一. Afinal 官方介绍: Afina ...
- vue.js学习之 跨域请求代理与axios传参
vue.js学习之 跨域请求代理与axios传参 一:跨域请求代理 1:打开config/index.js module.exports{ dev: { } } 在这里面找到proxyTable{}, ...
- IE中的activex控件
1.tree控件 DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HE ...