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. 使用Python3.7+Tornado5.1集成新浪微博三方登录(无需企业资质)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_137 新浪微博:山寨版的twitter,各种粉丝的集散地,天朝人民的最爱,基本上网民都人手一个微博账号,所以使用新浪微博账号进行三 ...

  2. Jittered采样类定义和测试

    抖动采样算法测试,小图形看不出什么明显区别,还是上代码和测试图吧. 类声明: #pragma once #ifndef __JITTERED_HEADER__ #define __JITTERED_H ...

  3. servlet映射路径匹配解析

    开头 servlet是javaweb用来处理请求和响应的重要对象,本文将从源码的角度分析tomcat内部是如何根据请求路径匹配得到处理请求的servlet的 假设有一个request请求路径为/tex ...

  4. django中的forms组件

    form介绍 用户需要向后端提交一些数据时,我们常常把这些数据放在一个form表单里,采用form标签,里面包含一些input等标签把用户的数据提交给后端. 在给后端提交数据的时候,我们常常也需要对于 ...

  5. 简单理解 Webpack,以及Web前端使用打包工具的原因

    Java 中的模块 传统的前端开发就是 JS.HTML.CSS 三件套.Web 没有像 Java 一样拥有优秀的模块机制,就是类与类之间可以分装在不同的包下,不同包下的类互相引用时通过import导入 ...

  6. 硬件错误导致的crash

    [683650.031028] BUG: unable to handle kernel paging request at 000000000001b790--------------------- ...

  7. [CF1538E] Funny Substrings (模拟)

    题面 该场 Div. 3 最"难"的一道题:Funny Substrings O I D \tt OID OID 队长喜欢玩字符串,因为 " O n e I n D a ...

  8. MapReduce计算流程

    MapReduce的计算流程 1.1 原始数据File The books chronicle the adventures of the adolescent wizard Harry Potter ...

  9. Spark 写 Hbase

    package com.grady import org.apache.hadoop.hbase.HBaseConfiguration import org.apache.hadoop.hbase.c ...

  10. python3实现:进程遇Error定时重启

    import os import time # 停止HFish def stopHFish(): # while True: try: # 找到HFish进程号 HFish_id = int(os.p ...