JOISC 2018 记录
Day1 T1 Construction of Highway
每一次操作形如查询一条到根的链上的逆序对数,然后将这条链的权值全部修改成同一个权值。
发现这个操作类似于 LCT 的 Access 操作,由此我们还可以知道对于所有的 \(n\) 次操作提取出来的 \(n\) 条要求逆序对数的序列,权值不同的只有 \(O(n\log n)\) 段。
所以每一次在 Access 的过程中提取权值相同的连续段,然后用树状数组求逆序对数即可,时间复杂度 \(O(n\log^2 n)\)。
Day1 T2 Fences
由于不能经过中心的 \([-S,S]\times [-S,S]\) 的区域,所以可以将这个正方形的四个顶点作为四条线段,这样所有可能选择修建的围栏都是再线段和线段之间的了。
然后我们考虑两条线段之间的最短路径可能是什么:两条线段端点之间的连边,一条线段的端点到另一条线段的垂线。我们可以直接计算出这八条边,选择其中合法的(即起点和终点都在线段上,且没有经过中心的正方形)最短的线段。这就是他们之间的路径。
这样我们可以计算出两两之间的路径,而我们要找到能够圈住中心正方形的一条路径。考虑从正方形内部引出一条射线,这包含这个正方形的路径必然经过这条射线奇数次。所以我们考虑给我们之前找到的路径附一个 0/1 权值,表示经过射线的次数的奇偶性。
但是考虑到路径不一定是从线段的端点处开始的,所以我们要规范化每条路径:给每条线段钦定一个端点,每条路径变成: 一条线段的钦定端点 \(\to\) 这条线段上路径端点 \(\to\) 另一条线段上路径端点 \(\to\) 另一条线段的钦定端点。
规范化了所有路径之后就可以直接跑 floyd 了,时间复杂度 \(O(n^3)\)。
Day1 T3 Tents
根据帐篷方向的要求可以得到每一个帐篷只可能的三种状态:同行同列没有其他帐篷;同行有一个帐篷,同列没有帐篷;同行没有帐篷,同列有一个帐篷。
记 \(f_{i,j}\) 表示处理了 \(i\) 行,它们占用了 \(j\) 列(每一列至少一个帐篷)的方案数。
转移可以讨论下一行是否放帐篷,放帐篷放那种状态的帐篷来得到转移。
时间复杂度 \(O(n^2)\)。
Day2 T1 Asceticism
相当于要将 \(1\sim n\) 分成 \(k\) 个集合,不能有空集,集合与集合之间有区别,直接考虑容斥:
\(f_i=\sum\limits_{j=1}^i(-1)^{i-j}j^n\dbinom{i}{j}\)。
但是这样会有重复计算的情况,也就是可能会出现两个相邻的集合 \(S_1\) 和 \(S_2\),出现 \(\max\limits_{i\in S_1}i<\min\limits_{i\in S_2}i\),由于需要进行最优的操作,所以这两个集合会被合并成同一个集合。
我们记 \(ans_i\) 为 \(k=i\) 时的答案,则我们可以通过对于 \(i<k\) 的 \(ans_i\) 分割集合来表示 \(k\) 个集合时的方案。其中 \(i\) 变成 \(k\) 需要分割 \(k-i\) 次。
则有 \(f_i=\sum\limits_{j=1}^i\dbinom{n-j}{i-j}ans_j\)。
记 \(f'_i=f_{n-i}\),\(ans'_i=ans_{n-i}\),代入上式得 \(f'_i=\sum\limits_{j=i}^n\dbinom{j}{i}ans'_j\)。
这是经典得二项式反演得式子,所以我们有 \(ans'_i=\sum\limits_{j=i}^n(-1)^{j-i}\dbinom{j}{i}f'_j\)。
所以 \(ans_i=\sum\limits_{j=1}^i(-1)^{i-j}\dbinom{n-j}{n-i}f_j\)。
有 \(ans_i=\sum\limits_{j=1}^i(-1)^{i-j}\dbinom{n-j}{n-i}\sum\limits_{k=1}^j(-1)^{j-k}k^n\dbinom{j}{k}\)。
交换和式顺序,有 \(ans_i=\sum\limits_{k=1}^i(-1)^{i-k}k^n\sum\limits_{j=k}^i\dbinom{n-j}{n-i}\dbinom{j}{k}\)。
考虑 \(\sum\limits_{j=k}^i\dbinom{n-j}{n-i}\dbinom{j}{k}\) 的组合意义,相当于是在 \(n+1\) 个数中先选择一个数,然后在它前面选择 \(n-i\) 个数,后面选 \(k\) 个数。
也就是有 \(\sum\limits_{j=k}^i\dbinom{n-j}{n-i}\dbinom{j}{k}=\dbinom{n+1}{n-j+k+1}=\dbinom{n+1}{j-k}\)。
最终有 \(ans_i=\sum\limits_{k=1}^i(-1)^{i-k}k^n\sum\limits_{j=k}^i\dbinom{n-j}{n-i}\dbinom{j}{k}\),直接计算即可。
时间复杂度 \(O(n+k\log n)\)。
Day2 T2 Road Service
由于是提交答案,考虑模拟退火。
通过对于小数据的求解,以及大胆猜测可知,添加的 \(k\) 条边有一个公共端点 \(rt\) 的时候是比较优的,考虑依次为基础进行退火,会节省大大减少状态量。
如果直接以答案作为估价函数,单次计算的复杂度为 \(O(n^2)\),代价太大。由于我们已经钦定了连边方式是菊花,所以我们可以以 \(\sum\limits_{i=1}^n\operatorname{dis}(rt,i)\) 作为估价函数,这样比较接近实际的答案,同时也将计算的复杂度降低到了 \(O(n)\)。
现在解决了计算贡献的问题,但是在退火的过程中,我们不太可能改变 \(rt\),所以我们需要一个初始就比较优的 \(rt\) 来作为初始状态。我们可以对于每一个点作为 \(rt\) 随机 \(5\) 的初始状态,\(O(n^2)\) 计算它们的估价函数,再取前 \(10\) 优的状态进行退火。
多跑几次就跑出来了。
Day2 T3 Worst Reporter 3
通过归纳证明或者找规律可以得到,每个人都存在一个权值 \(f_i\),他的走路策略是每 \(f_i\) 秒走 \(f_i\) 步。而且有 \(f_{i-1}|f_{i}\)。
因此,\(f_i\) 是单调不降的,而且本质不同的 \(f_i\) 只会有 \(O(\log V)\) 个。暴力计算出这 \(O(\log V)\) 段,每一次询问的时候对于每一段查询其所在的位置即可,时间复杂度 \(O(n+q\log V)\)。
Day3 T1 Airline Route Map
考虑到我们可以额外添加 12 个节点,量级近似于 \(log_2n\),所以考虑二进制分组。
取出 10 个点,每一个原本的点和其所有为 1 的二进制位对应的点连边。现在的问题转化成如何找到这 10 个点及其对应顺序。
要保证顺序可以将它们连成一条链,同时对应 \(2^0\) 的点度数必然比对应 \(2^9\) 的度数大,由此可以唯一确定顺序。
用另外一个点向这 10 个点连边,现在的问题转化成找到这个点。再用一个点向所有除了我们要找的这个点之外的所有点连边,这个点必然是全局度数唯一最大的点,所以可以直接找到。
Day3 T2 Bitaro's Party
发现这个 DAG 上信息不是很好用 polylog 的数据结构维护,所以考虑阈值分治。
我们设定一个权值 \(B\),对于每一个点维护到达它的前 \(B+1\) 长路以及对应节点(每一个节点的路径只算一次),这样,如果不能参加的海狸数 \(Y\le B\),我们都可以在查询前 \(B\) 短路时找到答案。时间复杂度 \(O(mB+QB)\)。
对于 \(Y>B\) 的,我们重新进行一次拓扑排序来求得答案,而这样的询问最多只有 \(\dfrac{\sum Y}{B}\) 个,时间复杂度为 \(O(m\dfrac{\sum Y}{B})\)。
取 \(B=O(\sqrt{\sum Y})\),则最终时间复杂度为 \(O((m+Q)\sqrt{\sum Y})\)。
Day3 T3 Security Gate
考虑将括号序列转成 \(\pm 1\) 序列,其中 (
对应 \(1\),)
对应 \(-1\)。
考虑如何检验一个 \(pm 1\) 序列是否合法,我们及其前缀和数组为 \(\{S_i\}\)。
可以得到合法的条件是 \(S_i\ge 0\) 且 \(S_n=0\),但是考虑到描述限制有一个很强的 \(S_n=0\) 且格式很不对称,所以考虑将 \(S_n=0\) 替换成 \(S_i-S_n\ge 0\)。
这样的好处是,如果将整个括号串翻转加反转,\(S_i\ge 0\) 和 \(S_i-S_n\ge 0\) 的两个条件就互换的。
考虑我们操作了区间 \((l,r]\) 之后,\(S_i\) 的变化(满足 \(S_n=2(S_r-S_l)\))。
\(\begin{cases}S_i&,i\le l\\2S_l-S_i&,i\in (l,r)\\S_i-S_n&,r\le i\end{cases}\)
我们考虑根据上面两个条件的满足情况进行 DP。
两个条件均满足
也就是 \(S'\) 本身就是合法的,可以使用 \(O(n^2)\) 的 DP 直接算出。
只满足其中一个条件
不妨令满足的条件为 \(S_i-S_n\ge 0\),对于满足 \(S_i\ge 0\) 的可以在反转并翻转之后变成满足 \(S_i-S_n\ge 0\)。
则我们找到第一个 \(S_i<0\) 也就是 \(S_i=-1\) 的地方 \(p\),则必然有 \(l\le p\),根据贪心,我们必然选择最大的 \(S_l\) 作为左端点。
如果在 \((l,p)\) 中存在一个 \(S_r=S_l+S_n/2\),则我们可以直接选择它,必然能够满足条件。发现这等价于 \(S_l+S_n/2\ge 0\)。
现在考虑 \(S_l+S_n/2<0\) 的情况,我们需要在 \([p,n]\) 中找到一个 \(S_i=S_l+S_n/2\) 的位置,而且要满足 \(p\) 到这个位置的所有 \(S_i\le 2S_l\)。由此,我们必然选择最左的满足条件的 \(r\)。但是考虑到后缀没有办法得到有关 \(S_i\) 的信息,所以记 \(T_i=S_i-S_n\),则我们就是要找到一个 \(T_i=S_l-S_n/2\) 的位置,而且所有 \(i\in[p,r]\) 要满足 \(T_i\le 2S_l-S_n=2(S_l-S_n/2)\),发现所有的转移只与 \(k=S_l-S_n/2\) 有关,所以我们考虑枚举 \(k\)。
设计 DP 状态:
我们可以记 \(f_{i,j}\) 表示第 \(i\) 位为第一个 \(S_i<0\) 的位置,且前缀最大值(\(S_l\))为 \(j\) 的方案数。
这个数组可以通过 \(f'_{i,j,k}\) 表示处理了前 \(i\) 位,当前 \(S_i=j\),且前缀最大值位 \(k\) 的方案数的 DP 来得到。\(g_{i,j,0/1}\) 表示处理了 \(i\sim n\),当前 \(T_i=i\),是否确定了 \(r\) 的方案数。
最终对于答案做出的贡献是 \(\sum\limits_{k}\sum\limits_{p}\sum\limits_{S_l}f_{p,S_l}g_{p,-S_n-1,[S_l+S_n/2< 0]}\)。
两个条件均不满足
找到最小的 \(S_i<0\) 的 \(p\),以及最大的 \(T_i<0\) 的 \(q\)。显然有 \(p\le q\)。
而我们要找的 \(l,r\) 必然有 \(l<p\),\(q\le r\)。
我们仍考虑找到一个 \([0,p)\) 中 \(S\) 最大的位置作为左端点,那么我们就是要在 \(S_q\sim S_n\) 中找到一个 \(S_r=S_l+S_n/2\)。
记 \(S_q\sim S_n\) 中的最大值为 \(A\),如果 \(S_l+S_n/2\le A\),则必然可以找到满足条件的 \(r\);否则有 \(S_l+S_n/2> A\),那么对于反转过后的序列就有 \(S_l+S_n/2< A\),需要考虑剪掉被重复计算的 \(S_l+S_n/2=A\) 的情况。
那么对于 \((l,r)\),需要满足还是要 \(S_i\le 2S_l\) 。对于后缀考虑 \(T_i\),也就是要在 \(T\ge 0\) 的时候出现一次 \(T_i=S_l-S_n/2\),然后一直到 \(p\) 需要满足 \(T_i\le 2(S_l-S_n/2)\)。
前缀的 DP 仍然是 \(f\),对于后缀的 DP 需要修改一下。
记 \(g_{i,j,0/1/2}\) 表示当前处理了 \(i\sim n\) 且 \(T_i=j\) 的时候:
- 当前还没有确定 \(r\)。
- 当前确定了 \(r\),还没有确定 \(q\)。
- 当前确定了 \(q\)。
的方案数。
在最后一维不为 \(0\) 的时候有 \(j\le 2k\)。\(1\) 和 \(2\) 唯一的区别就是 \(2\) 的时候可以出现 \(j<0\)。
最终贡献为 \(\sum\limits_{k}\sum\limits_{p}\sum\limits_{S_l}f_{p,S_l}g_{p,-S_n-1,2}\)。
发现在 \(S_l+S_n/2=A\) 的时候出现重复计算,需要额外进行一次 DP,和上面的 DP 的区别在于在最后一维不是 \(2\) 的时候要有 \(T_i\le k\)。
总体时间复杂度为 \(O(n^3)\)。
Day4 T1 Candies
经典的返回贪心,选择一个不在边缘的糖 \(a_i\) 之后,删去 \(a_{i-1}\),\(a_i\) 和 \(a_{i+1}\),加入一个权值为 \(a_{i-1}+a_{i+1}-a_i\) 的糖,然后递归这个过程。
可以证明任何可能的情况都可以通过这样的操作得到,用数据结构维护当前最小值,时间复杂度 \(O(n\log n)\)。
Day4 T2 Library
考虑从 \(1\sim n\) 依次加入每一本书,如果总次数相对上一次没有增加,说明它与之前的某几本书相邻,可以通过二分答案来找到这本书,询问次数为 \(n\log_2n+O(n)\) 次,可以通过。
Day4 T3 Wild Boar
根据贪心,我们必然会选择最短路作为选择的路径。
但是由于不能走“回头路”,所以我们还需要找到起点和终点均与最短路不同的“次短路”。发现仍然不够,我们还需要起点和最短路不同,终点和次短路不同;起点和次短路不同,终点和最短路不同:这样的两条路径。
可以证明存在最优解必然在有这 4 种路径组合得到。
考虑如何维护快速的合并转移,对于每一个 A_{i-1},A_{i},A_{i+1},我们可以得到一个矩阵表示 A_{i-1} 到 A_i 的四条路径和 A_i 到 A_{i+1} 的四条路经之间分别是否可以转移。发现修改和查询类似 DDP,使用矩阵维护 min + 矩阵乘法即可。
可以使用线段树维护,时间复杂度 \(O(m^2\log m+n^2+L+T\log L)\)。
JOISC 2018 记录的更多相关文章
- JOISC 2018 Day 2 最差记者3
JOISC 2018 Day 2 最差记者3 题意: 数轴上有\(N\)个选手和一个旗手,旗手在位置\(0\)<第\(i\)人的位置为\(-i\),每个选手有一个参数\(D_i\).旗手每单 ...
- 「JOISC 2018 Day 3」比太郎的聚会
题解: 很套路的题目 我们按照询问中的不算的个数是否大于$block$分类 如果大于,就$O(n)dp$一下 如果小于,就预处理出到每个点前$block$小的点 $block取\sqrt{n}$的话复 ...
- 【LOJ2838】「JOISC 2018 Day 3」比太郎的聚会(设阈值预处理/分块)
点此看题面 大致题意: 给你一张\(DAG\),多组询问,每次问你在起点不为某些点的前提下,到达给定终点的最大距离是多少. 设阈值 由于限制点数总和与\(n\)同阶,因此容易想到去设阈值. 对于限制点 ...
- [LOJ #2833]「JOISC 2018 Day 1」帐篷
题目大意:有一个$n\times m$的网格图,若一个人的同一行或同一列有人,他就必须面向那个人,若都无人,就可以任意一个方向.若一个人无法确定方向,则方案不合法,问不同的方案数.$n,m\leqsl ...
- LOJ 2840「JOISC 2018 Day 4」糖
有趣的脑子题(可惜我没有脑子 好像也可以称为模拟费用流(? 我们考虑用链表维护这个东西 再把贡献扔到堆里贪心就好了 大概就是类似于有反悔机制的贪心?我们相当于把选中的一个打上一个-v的tag然后如果选 ...
- loj#2838 「JOISC 2018 Day 3」比太郎的聚会
分析 预处理每个点的前根号小的距离 对于每次询问删除点小于根号则已经处理好 否则直接暴力dp即可 代码 #include<bits/stdc++.h> using namespace st ...
- LOJ #2831. 「JOISC 2018 Day 1」道路建设 线段树+Link-cut-tree
用 LCT 维护颜色相同连通块,然后在线段树上查一下逆序对个数就可以了. code: #include <cstdio> #include <algorithm> #inclu ...
- 退役前的最后的做题记录upd:2019.04.04
考试考到自闭,每天被吊打. 还有几天可能就要AFO了呢... Luogu3602:Koishi Loves Segments 从左向右,每次删除右端点最大的即可. [HEOI2014]南园满地堆轻絮 ...
- 快速从SQL语法过度到Elasticsearch的DSL语法
目录 前言 bool-相当于一个括号 should-相当于or must-相当于and must_not-相当于 ! and term-相当于= terms-相当于in between-相当于rang ...
- 退役前的记录(2018.10.14-NOIP2018)
退役前的记录 诸位好,我是\(CJ\)最菜的\(Oier\),已经是\(G2\)的老年选手了,不知道什么时候就会退役了,总之\(G1\ double\)的机会已经没有了,去年因为联赛失利而止步,而今年 ...
随机推荐
- 2023第十四届极客大挑战 — WEB WP
说明:由于是从docx直接导入,因此鉴于docx的识别,文章有些图片里面有红色下划线,但不影响! 属实懒了!直接导入了...哈哈.凑合看吧!实在太多了.... EzHttp Post传参 查看源码 访 ...
- JMS Controller生命周期
- [转帖]Java 提速之 Large pages【译】
https://juejin.cn/post/7011002046899978253 一.前言 最近花了很多时间在 JVM 的内存预留代码上.它开始是因为我们得到了外部贡献,以支持在 Linux 上使 ...
- 通过宿主机查看K8S或者是容器内的Java程序的简单方法
通过宿主机查看K8S或者是容器内的Java程序的简单方法 背景 最近一个项目的环境出现了 cannot create native process 的错误提示 出现这个错误提示时, docker ex ...
- [转帖]Megacli常用命令汇总
MegaCli 是一款管理维护硬件 RAID 软件,可以通过它来了解当前 raid 卡的所有信息,包括 raid 卡的型号,raid 的阵列类型,raid 上各磁盘状态,等 .通常,我们对硬盘当前的状 ...
- [转帖]kubernetes service 和 kube-proxy详解
https://plantegg.github.io/2020/01/22/kubernetes%20service/ 性能情况.. service 模式 根据创建Service的type类型不同,可 ...
- [转帖]“炫技”还是“真硬核”,OpenPPL 实测阿里「倚天 710」芯片
http://www.voycn.com/article/xuanjihaishizhenyingheopenppl-shicealiyitian-710-xinpian 本文将以深度学习模型推理 ...
- [转帖]ARM64体系结构编程与实践:基础知识
ARM64体系结构编程与实践:基础知识 原创 异步社区 2022-03-30 12:44:16 著作权 文章标签 寄存器 体系结构 v8 ARM64体系结构 ARM 文章分类 物联网 阅读数1570 ...
- CentOS7上面一键部署rabbitmq的简单方法
1. rabbitmq的安装部署比redis之类的要麻烦一些. 主要是他是基于erlang写的 而不是基于c或者是c++写的 2. 很多时候编译需要添加很多组件, 但是一些机器可能不会让添加这么多的组 ...
- Docker容器基础入门认知-Namespce
在使用 docker 之前我一般都认为容器的技术应该和虚拟机应该差不多,和虚拟机的技术类似,但是事实上容器和虚拟机根本不是一回事. 虚拟机是将虚拟硬件.内核(即操作系统)以及用户空间打包在新虚拟机当中 ...