JOISC 2017 题解

JOISC2017 Day1 开荒者 Cultivation

首先进行转化,转化为对于每个点 \(x,y\),将其扩成一个左上角为 \((x-a,y-c)\) 右下角为 \((x+b,y+d)\) 的矩形后覆盖整个 \(R\times C\) 的大举行。首先考虑枚举 \(a,b\),那么我们可以得到平面上的几条垂直线段,那么我们可以得到一些关于 \(c,d\) 的不等式。对于每行,令其最左侧穿过的线段到第一列的距离为 \(f\),最右侧穿过线段到最后一列的距离为 \(g\),相邻两条穿过的线段最大间距为 \(h\),那么需要 \(c\ge f\)\(d\ge g\)\(c+d\ge h\)。也就是分别确定了最大的 \(f,g,h\) 就可以确定出最小的 \(c+d\)

但是这样复杂度是不可接受的。我们发现 \(a+b\) 不变的情况下,\(a\) 的变化只会导致 \(f,g,h\) 发生一些平移,不会改变值。我们可以直接枚举 \(a+b\),然后找到一个长度为 \(R\) 的区间,然后分别取区间内最大的 \(f,g,h\),这个东西可以单调队列维护。同时容易发现可能的 \(a+b\) 只有 \(O(n^2)\) 种(\(x_i-x_j\)\(C-x_i+x_j-1\))。同时我们发现对于一种 \(a+b=k\),它每一行所穿过的线段对应的点一定是将原先的所有点按 \(x\) 排序后的一段区间,所以我们提前预处理出区间的 \(f,g,h\) 即可 \(O(n^2\log n)\) 预处理,\(O(n^3)\) 求解。

https://qoj.ac/submission/108987

JOISC2017 Day1 港口设施 Port Facility

首先考虑使用 01 并查集。考虑扫描线,扫的时候扫到左端点就将这个点加入中,然后右端点就把仍然存在的且左端点位于 \([l_i+1,r_i-1]\) 的点和它进行连边(0连1,1连0),再把这个点给删掉。考虑把这个操作放到线段树上去,每次若这个区间中有点就对这个区间打上 tag,合并 tag 时只需要两个 tag 的点 0连0,1连1 地连边。每次删点的时候再把所有有关这个点的 tag 给下放。复杂度 \(O(n\cdot \log n\cdot\alpha(n))\)

实际上有更简单的解法:还是考虑那样连边,但是可以均摊暴力把每次要和当前点连边的点给合并了。这样就不需要线段树维护了。

https://qoj.ac/submission/108520

JOISC2017 Day1 手持花火 Sparklers

先二分 \(v\),然后把 \(v\) 乘到 \(T\) 上变成 \(v=1\),然后再 \(a\times 2\)\(T\times 2\) 规避分数。然后考虑最优情况一定是碰上不直接传火,而是跟着它走然后火没了再续上,这样就变成了只有一个移动的火把,然后遇到人可以续火。然后我们也一定是一直保持走动,遇到人再回头。我们我们遇到人之后,只需要考虑向左走还是向右走,于是相当于就是把 \(k\) 之前的人和 \(k\) 之后的人分开,\(a\) 为和前面一个人的距离,然后每次从两个队列中选一个头然后删掉,并获得 \(a-t\) 的代价。考虑划分连续段,先从前往后,如果段和 \(>0\) 就截断,可以截成一些和 \(>0\) 的段,然后记录每个段的最小前缀和,就可以贪心了。最后会剩下一个段和 \(<0\) 的段,可以从后往前考虑,就是相同的问题了,并且一定是能划分完的。复杂度 \(O(n\log V)\)

https://qoj.ac/submission/108573

JOISC2017 Day2 星穹铁道 Railway Trip

首先肯定是每个点不断往比自己大的点跳,然后两边同时跳到同一个点。考虑我们按照这种题的套路,每次记录能跳到的最左侧的点和最右侧的点,这样跳 \(x\) 步跳到的端点是唯一的。注意到,如果 \(u,v\) 分别跳 \(x,y\) 步到的这样的端点恰好无交,那么 \(u\) 的端点再跳一步一定能到达 \(v\) 的一个端点。而跳到恰好无交的过程是唯一的,所以直接先倍增 \(x\) 再倍增 \(y\) 即可。

https://qoj.ac/submission/108495

JOISC2017 Day2 门票安排 Arranging Tickets

https://www.cnblogs.com/TetrisCandy/p/17166793.html。这题过于厉害了。

JOISC2017 Day3 幽深府邸 Long Mansion

法一:直接暴力扩展,要注意继承能经过的点的答案,复杂度是正确的,但是不大会证明。

法二:令 \(f_l\) 表示 \(>l\) 的位置的第一次出现 \(c_l\) 的位置,\(g_r\) 表示 \(<r\) 的位置的第一次出现 \(c_r\) 的位置,那么对于 \(i\) 要找到极小的 \(i\in [l,r]\) 满足 \(r<f_l\)\(l>g_r\)。对于每个 \(l\) 记录最小的满足要求的 \(r\),然后更新区间的答案。

https://qoj.ac/submission/108097

JOISC2017 Day3 自然公园 Natural Park

首先考虑一种链的做法:维护一条包含 \(0\) 的链 \(x\to y\),对于要新加入的节点 \(z\),问出在 \(x\) 左边还是 \(y\) 右边。设在 \(y\) 右边,考虑 \(W(y,z)\) 表示问出 \(y,z\) 中间的链的过程,我们通过二分问出 \(y\to z\) 中的最小的点 \(w\),然后 \(W(y,w)\)\(W(w,z)\) 即可求出答案。

然后考虑树的做法:考虑维护当前的包含 \(0\) 的连通块,然后每次新加入的 \(z\),先问出一个 \(y\) 使得 \(y\to z\) 的路径使得不经过原连通块。这个可以边分治,然后看哪一半树上存在这样的 \(y\)。这同样可以对 dfs 序进行二分得到。问出 \(y\) 之后就可以 \(W(y,z)\) 了,分治理论复杂度 \(O(n\log_{1.2}n)\),但是跑不满。

然后考虑图的情况:我们仍然找到类似的 \(y\),方法仍然是对生成树进行边分治/二分,但是每次将一个点和原连通块相连的时候,需要把所有邻点问出来,这个和求 \(y\) 的方法本质相同,理论次数 \(kn\log_{1.2}n\),但是稍微剪枝一下就可以直接过。

https://qoj.ac/submission/108269

JOISC2017 Day4 绑架2 Abduction 2

考虑直接记忆化搜索,每次找到拐弯的点。复杂度我也不大会正,但是看上去非常对。

https://qoj.ac/submission/108328

posted @ 2023-05-27 07:28  LarsWerner  阅读(170)  评论(0编辑  收藏  举报