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.你可以 ...
随机推荐
- 创龙DSP6748开发板LED闪烁-第一篇
1. 首先看下DSP6748的GPIO寄存器的文档,先看下框图,有这个框图,一目了然,输入和输出很清楚 2. 看下寄存器部分,对应上面的图,问题在于,DSP6748有多少个GPIO?最多144个,下一 ...
- Sql Server Profiler使用
在使用Entity Framework的过程当中,有时候需要看Entity Framework自动生成的Sql语句,在客户端可以使用跟踪的方法看到每次查询时的Sql语句,其实通过数据库 ...
- 【JUC源码解析】AQS
简介 AQS,也即AbstractQueuedSynchronizer,抽象队列同步器,提供了一个框架,可以依赖它实现阻塞锁和相关同步器.有两种类型,独占式(Exclusive)和共享式(Share) ...
- unity面试题一
一:什么是协同程序? 在主线程运行的同时开启另一段逻辑处理,来协助当前程序的执行,协程很像多线程,但是不是多线程,Unity的协程实在每帧结束之后去检测yield的条件是否满足. 二:Unity3d中 ...
- uvaoj 133 - The Dole Queue(逻辑,环形队列数数)
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- 数据库Mysql的学习(四)-表的记录操作
,);//指定插入的顺序 ,);//按照默认的插入 ,),(,)(,);//同时插入多条数据 //将查询结果插入表中 CREATE TABLE TEXT( category_id INT PRIMAR ...
- spark-shell解析
spark-shell 作用: 调用spark-submit脚本,如下参数 --classorg.apache.spark.repl.Main --name "Spark shell&quo ...
- Docker容器的搭建
Docker容器的搭建 一.先从Docker Hub上面拉取一个基础镜像 命令:docker pull ubuntu 命令说明:pull:拉取镜像的命令,ubuntu:拉取镜像的名称 扩展命令: 命令 ...
- Nodejs基础之redis
安装redis 模块 npm install redis 1 代码部分 const redis = require('redis') const client = redis.createClient ...
- Linux内核设计笔记13——虚拟文件系统
虚拟文件系统 内核在它的底层文件系统系统接口上建立一个抽象层,该抽象层使Linux可以支持各种文件系统,即便他们在功能和行为上存在很大差异. VFS抽象层定义了各个文件系统都支持的基本的.概念上的接口 ...