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 ...
随机推荐
- vue 安装 fontawesome
查看最新版的fontawesome 信息: https://github.com/FortAwesome/vue-fontawesome 搜索图标 :https://fontawesome.com/i ...
- Centos 设置时区
参考网址: http://jingyan.baidu.com/article/636f38bb268a82d6b84610bd.html //打开设置 tzselect //选择 )Asia → )c ...
- Thinkphp [美味]常用代码
//调试开关 function _initialize () { // 调试开关 C ( 'SHOW_PAGE_TRACE', TRUE ); } //判断 IS_AJAX && $t ...
- Mybatis insert返回主键ID
Mybatis insert语句书写 <insert id="insertSelective" useGeneratedKeys="true" keyPr ...
- android 复制到剪切板
The Clipboard Framework 当使用clipboard framework时,把数据放在一个剪切对象(clip object)里,然后这个对象会放在系统的剪贴板里. clip obj ...
- angular4 Form表单相关
ng4中,有两种方式去声明一个表单 一:Template-Driven Forms - 模板驱动式表单 [引入FormsModule] 1.ngForm赋值 [可以方便的获取表单的值] <f ...
- spring boot resttemplate发送post,get请求
参考博客: https://blog.csdn.net/weixin_42456466/article/details/80728387 https://www.cnblogs.com/QQParad ...
- @at-root和#{&}结合
Sass有脚本模式#{},他和&不同之处是,&只用作选择器,它只能出现在一个复合的开始选择器,类似于一个类型选择器,如a或者h1.但#{}他表示的是一个插值,它可以用在任何地方.同样的 ...
- php 如何生成静态页
PHP文件名:dome.php <?php $string = 1; ob_start(); @readfile("templets/list.html"); $text = ...
- [C#] 使用WebSocket进行通讯
客户端 客户端很简单 string url = "ws://localhost:24900/" + "test.ashx"; try { System.Net. ...