HZOJ Function
比较神仙的一道dp,考试的时候还以为是打表找规律啥的。
我们重新描述一下这道题:一个10 9 × n的网格,每个格子有一个权值,每一列格子的权值都是相同的。从一个起点开始,每次可以向上走一格或者向左上角走一格,直到走到最上面一行为止,你需要最小化经过的格子的总权值。
然而我并没有看出来。
首先我们可以发现一些显然的性质,最优的路径之一一定形如:先往左上走若干步(可能不走),到达权值较小的一列后,一直往上走到顶。对于每个询问,枚举从起点出发最终会到达哪一列,就可以得到一个O(nq)的做法。
然而我也没有想到……
算了直接把作者的题解全放出来吧:
对于任意1 ≤ i ≤ j ≤ n, 从(x, j)出发最终到达第i列然后走到顶的代价,可以表示为一个关于x的一次函数,我们只关心这些一次函数的最小值,也就是这些直线形成的下凸壳。我们得到一个思路:将询问离线,按y从小到大排序,从最左边开始每次加入一条直线,维护下凸壳,然后在凸壳上二分即可得到答案。怎么维护下凸壳呢?对于一个点(x, y),它要么继承上一列x − 1的决策,要么就直接往上走到顶。并且我们发现,第二种情况只会出现在从顶端开始连续的一段中。于是我们只需要用栈维护凸壳即可。O((n + q) log n).
刚开始没怎么看懂,好像我的做法和题解也不是很一样,其实现在还有一些细节没有搞明白……
首先看暴力的式子:$ans=min(ans,sum[y(i)]-sum[j]+(x(i)-y(i)+j)*A[j])$
在y固定时,他是一个关于x的一次函数,即$y=kx+b$的形式,设走到j时停止然后向上走,那么$k=A[j],b=sum[y]-sum[j]+(j-y)*A[j]$
对于每一个j都是一条直线,那么这些直线构成了一个上凸壳。
我们可以用On的复杂度枚举y,用栈维护凸壳(添加直线是加在了坐标系的最左边),考虑y增加会给直线造成什么影响,只会使直线的截距发生改变而斜率不变,所以原来的凸壳仍然是对的。
那么考虑如何吧j=y的这条之间加入凸壳,首先将斜率大于这条直线的栈顶直线弹掉,然后交点也得是单调的,继续弹掉不合法的,(自己yy一下坐标系,横轴是询问的x,纵轴为最优解),
然后处理当前y的询问,直接二分栈找到当前x在坐标系中对应的直线就可以了(一定注意栈顶其实是坐标轴最左边的直线)。
放下代码(稍恶心):
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define st sta[top]
#define sm sta[mid]
#define sm1 sta[mid+1]
#define st1 sta[top-1]
#define int LL
#define LL long long
using namespace std;
struct ques
{
int x,y,id;
#define x(i) que[i].x
#define y(i) que[i].y
#define id(i) que[i].id
friend bool operator < (ques a,ques b)
{return a.y<b.y;}
}que[];
int n,A[],q,maxx;
LL sum[],al[];
LL sta[],top;
double getx(int k1,int k2,int j1,int j2){return (double)(j2-j1)/(double)(k1-k2);}
inline int read();
signed main()
{
// freopen("function2.in","r",stdin);
// freopen("out.out","w",stdout); n=read();
for(int i=;i<=n;i++)A[i]=read(),sum[i]=sum[i-]+A[i];
q=read();
for(int i=;i<=q;i++)x(i)=read(),y(i)=read(),id(i)=i;
sort(que+,que+q+); int now=;
for(int y=;y<=n;y++)
{
while(top&&A[sta[top]]>=A[y])top--;
while(top>&&
getx(A[y],A[st],,sum[y]-sum[st]+A[st]*(st-y))
>=getx(A[st1],A[st],sum[y]-sum[st1]+A[st1]*(st1-y),sum[y]-sum[st]+A[st]*(st-y))
)top--;
sta[++top]=y;
for(;y(now)==y&&now<=q;now++)
{
int l=,r=top,mid;
while(l<r)
{
mid=(l+r)>>;
double tx=getx(A[sm],A[sm1],sum[y]-sum[sm]+A[sm]*(sm-y),sum[y]-sum[sm1]+A[sm1]*(sm1-y));
if(x(now)<=tx)l=mid+;
else r=mid;
}
mid=l;
al[id(now)]=sum[y]-sum[sm]+A[sm]*(x(now)-y+sm);
} }
for(int i=;i<=q;i++)printf("%lld\n",al[i]);
}
inline int read()
{
int s=,f=;char a=getchar();
while(a<''||a>''){if(a=='-')f=-;a=getchar();}
while(a>=''&&a<=''){s=s*+a-'';a=getchar();}
return s*f;
}
HZOJ Function的更多相关文章
- 通过百度echarts实现数据图表展示功能
现在我们在工作中,在开发中都会或多或少的用到图表统计数据显示给用户.通过图表可以很直观的,直接的将数据呈现出来.这里我就介绍说一下利用百度开源的echarts图表技术实现的具体功能. 1.对于不太理解 ...
- jsp中出现onclick函数提示Cannot return from outside a function or method
在使用Myeclipse10部署完项目后,原先不出错的项目,会有红色的叉叉,JSP页面会提示onclick函数错误 Cannot return from outside a function or m ...
- JavaScript function函数种类
本篇主要介绍普通函数.匿名函数.闭包函数 目录 1. 普通函数:介绍普通函数的特性:同名覆盖.arguments对象.默认返回值等. 2. 匿名函数:介绍匿名函数的特性:变量匿名函数.无名称匿名函数. ...
- 在ubuntu16.10 PHP测试连接MySQL中出现Call to undefined function: mysql_connect()
1.问题: 测试php7.0 链接mysql数据库的时候发生错误: Fatal error: Uncaught Error: Call to undefined function mysqli_con ...
- jquery中的$(document).ready(function() {});
当文档载入时执行function函数里的代码, 这部分代码主要声明,页面加载后 "监听事件" 的方法.例如: $(document).ready( $("a") ...
- Function.prototype.toString 的使用技巧
Function.prototype.toString这个原型方法可以帮助你获得函数的源代码, 比如: function hello ( msg ){ console.log("hello& ...
- 转:ORA-15186: ASMLIB error function = [asm_open], error = [1], 2009-05-24 13:57:38
转:ORA-15186: ASMLIB error function = [asm_open], error = [1], 2009-05-24 13:57:38http://space.itpub. ...
- [Xamarin] 透過Native Code呼叫 JavaScript function (转帖)
今天我們來聊聊關於如何使用WebView 中的Javascript 來呼叫 Native Code 的部分 首先,你得先來看看這篇[Xamarin] 使用Webview 來做APP因為這篇文章至少講解 ...
- Oracle数据库自动备份SQL文本:Procedure存储过程,View视图,Function函数,Trigger触发器,Sequence序列号等
功能:备份存储过程,视图,函数触发器,Sequence序列号等准备工作:--1.创建文件夹 :'E:/OracleBackUp/ProcBack';--文本存放的路径--2.执行:create or ...
随机推荐
- 通过inputSplit分片size控制map数目
前言:在具体执行Hadoop程序的时候,我们要根据不同的情况来设置Map的个数.除了设置固定的每个节点上可运行的最大map个数外,我们还需要控制真正执行Map操作的任务个数. 1.如何控制实际运行的m ...
- vue使用填坑之:model和v-model的区别
v-model通常用于input的双向数据绑定 <input v-model="parentMsg">,也可以实现子组件到父组件数据的双向数据绑定:首先说说v-mode ...
- 二维码识别项目zxing横屏改为竖屏
第1步: 在AndroidManifest中将CaptureActivity的screenOrientation属性做如下修改: android:screenOrientation="por ...
- 在redhat 6.6上安装Docker
安装环境 支持Docker的RHEL版本 Red Hat Enterprise Linux 7 (64-bit) Red Hat Enterprise Linux 6.5 (64-bit) 或更高版本 ...
- 调试R代码中出现的常用的函数
1. 字符串连接函数 paste的一般使用格式为: paste(..., sep = " ", collapse = NULL) ...表示一个或多个R可以被转化为字符型的对象:s ...
- MaxCompute推出面向开发者的专属版本,普惠大数据开发者
3月20号,阿里云正式对外宣布推出MaxCompute产品的新规格-开发者版.MaxCompute开发者版是阿里云大数据计算服务发布的开发者专属版本.区别于原有的按量付费.按CU预付费规格,开发者版是 ...
- Tool-图片压缩-腾讯智图:腾讯智图
ylbtech-Tool-图片压缩-腾讯智图:腾讯智图 智图是腾讯ISUX前端团队开发的一个专门用于图片压缩和图片格式转换的平台,其功能包括针对png,jpeg,gif等各类格式图片的压缩,以及为上传 ...
- MSSQL 为db创建user
use [IBatisNet]GO if not exists (select * from master.dbo.syslogins where loginname = N'IBatisNet')B ...
- dialog的进度条
import android.app.Activity; import android.app.ProgressDialog; import android.os.Bundle; import and ...
- 利用幂等性区分HTTP的POST与PUT请求
1.什么是幂等性 幂等性概念:幂等通俗来说是指不管进行多少次重复操作,都是实现相同的结果. 2.REST请求中哪些是幂等操作 GET,PUT,DELETE都是幂等操作,而POST不是,以下进行分析: ...