Solution

考虑从\((x_1,y_1)\)走到\((x_2,y_2)\)满足只改变一次方向,则容易求出先向南走当且仅当

\[\frac{a_{x_1} - a_{x_2}}{x_1 - x_2}<\frac{b_{x_1} - b_{x_2}}{x_1 - x_2}
\]

我们思考,没有用的行或列满足什么条件。

以行为例,考虑有三行:\(x=i, x=j,x=k\),两列:\(y=l,y=r\),从\((i,l)\)走到\((k,r)\)我们的条件是在\(x=j\)上走过一定更劣,故而能将\(x=j\)删去

假设我们从经\(x=j\)走到了,那么可以得到

\[\frac{a_{i} - a_{j}}{i - j}<\frac{b_{l} - b_{r}}{l - r}
\]

到这里有一个比较容易想到的构造:若

\[\frac{a_{i} - a_{j}}{i - j}>\frac{a_{j} - a_{k}}{j - k}
\]

则不会从\((j,l)\)经过\(x=j\)走到\((k,r)\)

所以我们要对\((i,a_i)\)维护出一个斜率单调递增的凸包,那么在凸包上的行就是可能有用的

对于列,同理

然后呢?如何求答案?

需要注意的是,在求答案的时候不能一次跳一个矩形的两条边,因为我们上面的条件是在只改变一次方向的情况下的,正确的方式是在\((x,y)\)的位置通过比较开头的式子,来决定先往哪个方向走,但是只走一段,因为通过去掉重复的部分可以发现走出的每一步都需要依赖于开头的式子,而走出一步后,状态发生改变,所以要重新找出最优决策。可以通过维护两个指针实现,复杂度\(O(H+W)\)

Code

#include <cstdio>
#include <iostream>
#define LL long long
using namespace std;
inline LL read() {
LL res = 0, f = 0; char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) res = (res << 1) + (res << 3) + (ch ^ 48);
if(f) res = ~res + 1;
return res;
}
const int N = 1000100;
LL h, w, a[N], b[N], ans, stk[N], top, p[N], q[N];
inline double slope1(LL x, LL y) {return 1.0 * (a[x] - a[y]) / (x - y);}
inline double slope2(LL x, LL y) {return 1.0 * (b[x] - b[y]) / (x - y);}
inline LL calc(LL x, LL y, LL nx, LL ny) {
if(x == nx) return a[x] * (ny - y);
else return b[y] * (nx - x);
}
int main() {
h = read(), w = read();
for(int i = 1; i <= h; ++i) a[i] = read();
for(int i = 1; i <= w; ++i) b[i] = read();
for(int i = 1; i <= h; ++i) {
while(top > 1 && slope1(i, stk[top - 1]) < slope1(stk[top], stk[top - 1])) --top;
stk[++top] = i;
}
for(int i = 1; i <= top; ++i) p[i] = stk[i];
top = 0;
for(int i = 1; i <= w; ++i) {
while(top > 1 && slope2(i, stk[top - 1]) < slope2(stk[top], stk[top - 1])) --top;
stk[++top] = i;
}
for(int i = 1; i <= top; ++i) q[i] = stk[i];
for(int p1 = 1, p2 = 1, x = 1, y = 1; !(x == h && y == w); ) {
if(x == h) ans += calc(x, y, x, q[++p2]), y = q[p2];
else if(y == w) ans += calc(x, y, p[++p1], y), x = p[p1];
else {
if(slope1(p[p1], p[p1 + 1]) < slope2(q[p2], q[p2 + 1])) ans += calc(x, y, p[++p1], y), x = p[p1];
else ans += calc(x, y, x, q[++p2]), y = q[p2];
}
}
printf("%lld\n",ans);
}

「JOISC 2022 Day1」京都观光 题解的更多相关文章

  1. 【LOJ】#3032. 「JOISC 2019 Day1」馕

    LOJ#3032. 「JOISC 2019 Day1」馕 处理出每个人把馕切成N段,每一段快乐度相同,我们选择第一个排在最前的人分给他的第一段,然后再在未选取的的人中选一个第二个排在最前的切一下,并把 ...

  2. 【LOJ】#3031. 「JOISC 2019 Day1」聚会

    LOJ#3031. 「JOISC 2019 Day1」聚会 听说随机可过? 我想了很久想了一个不会被卡的做法,建出前\(u - 1\)个点的虚树,然后找第\(u\)个点的插入位置,就是每次找一条最长链 ...

  3. 【LOJ】#3030. 「JOISC 2019 Day1」考试

    LOJ#3030. 「JOISC 2019 Day1」考试 看起来求一个奇怪图形(两条和坐标轴平行的线被切掉了一个角)内包括的点个数 too naive! 首先熟练的转化求不被这个图形包含的个数 -- ...

  4. 「JOISC 2014 Day1」巴士走读

    「JOISC 2014 Day1」巴士走读 将询问离线下来. 从终点出发到起点. 由于在每个点(除了终点)的时间被过来的边固定,因此如果一个点不被新的边更新,是不会发生变化的. 因此可以按照时间顺序, ...

  5. 「JOISC 2014 Day1」 历史研究

    「JOISC 2014 Day1」 历史研究 Solution 子任务2 暴力,用\(cnt\)记录每种权值出现次数. 子任务3 这不是一个尺取吗... 然后用multiset维护当前的区间,动态加, ...

  6. 「题解」「JOISC 2014 Day1」历史研究

    目录 题目 考场思考 思路分析及标程 题目 点这里 考场思考 大概是标准的莫队吧,离散之后来一个线段树加莫队就可以了. 时间复杂度 \(\mathcal O(n\sqrt n\log n)\) . 然 ...

  7. 「JOISC 2014 Day1」历史研究 --- 回滚莫队

    题目又臭又长,但其实题意很简单. 给出一个长度为\(N\)的序列与\(Q\)个询问,每个询问都对应原序列中的一个区间.对于每个查询的区间,设数\(X_{i}\)在此区间出现的次数为\(Sum_{X_{ ...

  8. 「JOISC 2020 Day1」汉堡肉

    我终于学会打开机房的LOJ了! description LOJ3272 有\(n(n<=2*10^5)\)个矩形,让你找\(k(k<=4)\)个点可以覆盖所有矩形(点可重复),输出一种方案 ...

  9. 「JOISC 2019 Day3」穿越时空 Bitaro

    「JOISC 2019 Day3」穿越时空 Bitaro 题解: ​ 不会处理时间流逝,我去看了一眼题解的图,最重要的转换就是把(X,Y)改成(X,Y-X)这样就不会斜着走了. ​ 问题变成二维平面上 ...

随机推荐

  1. YII扩展功能图

  2. SQL Server查询优化

    从上至下优化 看过一篇文章,印象深刻,里面将数据库查询优化分为四个大的方向 使用钞能力--给DB服务器加物理配置,内存啊,CPU啊,硬盘啊,全上顶配 替换存储系统--根据实际的业务情况选择不同的存储数 ...

  3. js仿toDoList(待办事项)练习

    JS的一个小练习 展示成果 话不多说 html骨架 <!DOCTYPE html> <html lang="en"> <head> <me ...

  4. LuoguP1922 女仆咖啡厅桌游吧 (树形动态规划)

    #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> ...

  5. java学习第七天xml.day18

    反射 在java中,反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力. 获取字节码的方式: 使用反射获取构造器 : 内省

  6. .NET WebAPI 采用 IDistributedCache 实现分布式缓存过滤器 Redis 模式

    分布式缓存是由多个应用服务器共享的缓存,通常作为访问它的应用服务器的外部服务进行维护. 分布式缓存可以提高 ASP.NET Core 应用的性能和可伸缩性,尤其是当应用由云服务或服务器场托管时. 与其 ...

  7. 教程 - 深度探讨在 Vue3 中引入 CesiumJS 的最佳方式

    目录 1. 你应该先知道的基础知识 1.1. CesiumJS 的库构成 1.2. 选择 Vite3 和 pnpm 的理由 1.3. 使用 External 模式引入静态库 - 不打包静态库 1.4. ...

  8. HOSMEL:一种面向中文的可热插拔模块化实体链接工具包

    HOSMEL: A Hot-Swappable Modularized Entity Linking Toolkit for Chinese ACL 2022 论文地址:https://aclanth ...

  9. 一 策略模式 来自CBF4LIFE 的设计模式

    刘备要到江东娶老婆了,走之前诸葛亮给赵云(伴郎)三个锦囊妙计,说是按天机拆开解决棘手问题,嘿,还别说,真是解决了大问题,搞到后是周瑜陪了夫人又折兵呀,那咱们先看看这个场景是什么样子的. 先说这个场景中 ...

  10. openstack 搭建详细步骤

    该博文转载于(https://www.cnblogs.com/whwh/p/16200004.html) 一.openstack单点部署 1.配置虚拟机NAT网络连接 查看vmware的NAT网络默认 ...