记录一下 JOISC 2023 的做题记录

Day1 T1 Two Currencies

给定一棵树,在边上有总计 \(m\) 个检查站,经过一个检查站需要叫 \(1\) 枚金币或者若干枚银币。\(Q\) 次询问,问一个人有 \(X\) 枚金币和 \(Y\) 枚银币,能否从 \(u\) 走到 \(v\),同时回答最多可以留下多少枚金币。

发现一定是用银币卖掉价值路径上银币代价前 \(k\) 小的检查站,考虑用整体二分,使用树状数组维护重链剖分维护,时间复杂度 \(O(n\log^3n)\)。

Day1 T2 Festivals in JOI Kingdom 2

给出一个错误的贪心方式,问有多少种构造可以使得这个DP假掉。

首先我们要知道正确的 DP 怎么写。

将所有的区间按照右端点排序,每一次选择右端点最小且与没有与已经选择的区间有交的区间。

我们称正确的算法选中的区间为红区间,错误的算法选中的区间为蓝区间,两个算法都选择了的区间叫做紫区间,两个算法都没有选择的区间叫做黑区间。

显然,任何红区间两两无交,蓝区间两两无交。

而且,相邻的两个红区间的右端点之间不会包含任何的完整区间;相邻两个蓝区间的左端点之间不会包含任何区间的左端点。

我们不好考虑红区间比蓝区间多的情况,但是我们可以考虑他们相等的情况,然后用 \(\prod\limits_{i=1}^{N} (2*i-1)\) 减去即可。

则我们可以将红蓝区间两两配对,则红蓝数量相等的情况下,每一对红蓝区间必然有交。

我们还可以证明第 \(i\) 个红区间的右端点必然大于第 \(i-1\) 个蓝区间的右端点(否则红蓝无法匹配),必然小于第 \(i\) 个蓝区间的右端点(否则不满足正确算法的贪心)。

由于所有的红蓝区间是配对的,所以考虑依次插入每一对红蓝区间。

插入的同时,我们可以处理所有右端点在两次的红区间之间的所有黑区间,这些区间的左端点必然在上一个红区间的右端点之前。

所以我们需要设计状态:\(f_{i,k,0/1}\) 表示插入了前 \(i\) 个红蓝区间,预留了 \(k\) 个空位给黑区间的左端点。转移需要枚举插入的黑区间数 \(j\),复杂度是 \(O(n^3)\) 的。

枚举插入的黑区间数是不可避免地,考虑优化DP的状态。

我们发现我们专门用了一位 \(k\) 来维护黑区间的左端点,所以考虑反转整个过程,\textbf{从右向左}加入每一对红蓝区间,只需要保证插入的黑区间右端点在上一个红区间的右端点之后即可。而对于这些黑区间的左端点,只需要保证不在下一个区间的右端点和上一个区间的左端点之间即可。

考虑设计状态:\(f_{i,0/1}\) 表示插入了后 \(i\) 个区间,由多少种方案,转移枚举插入的黑区间数 \(j\)。

对于转移来源和转移结果的 \(0/1\) 状态不同,我们可以得到如下的四种转移:

\(f_{i+j+2,1}\gets f_{i+j+2,1}+f_{i,1}\times (j+1)\times (j+2)\times (2i-3+j)^{\underline{j}}\)。

\(f_{i+j+1,0}\gets f_{i+j+2,0}+f_{i,1}\times (j+1)\times (2i-3+j)^{\underline{j}}\)。

\(f_{i+j+2,1}\gets f_{i+j+2,1}+f_{i,0}\times (j+1)\times (2i-2+j)^{\underline{j}}\)。

\(f_{i+j+1,0}\gets f_{i+j+2,0}+f_{i,0}\times (2i-2+j)^{\underline{j}}\)。

这样就可以做到 \(O(n^2)\) 的复杂度,卡一卡常就可以通过了。

但是还可以优化,状态不可能再优化了,所以考虑优化转移。

例如对于第一个转移:

\(f_{i+j+2,1}+= f_{i,1}\times (j+1)\times (j+2)\times (2i-3+j)^{\underline{j}}\)

我们令 \(k=i+j+2\),可以得到:

\[\begin{matrix}
f_{i,1}\times (j+1)\times (j+2)\times (2i-3+j)^{\underline{j}}\\
=f_{i,1}\times (j+1)\times (j+2)\times \frac{(2i-3+j)!}{(2i-3)!}\\
=\frac{f_{i,1}}{(2i-3)!}\times (i+k-5)!\times (k-i)\times (k-i-1)\\
=\frac{f_{i,1}}{(2i-3)!}\times (i+k-5)!\times \left[i^2+(1-2k)i+k^2-k\right]\\
=\left[\frac{i^2f_{i,1}}{(2i-3)!}+(1-2k)\frac{if_{i,1}}{(2i-3)!}+(k^2-k)\frac{f_{i,1}}{(2i-3)!}\right]\times (i+k-5)!
\end{matrix}\]

发现式子中只有 \(i\) 和 \(i+k\),我们最终要得到的是 \(k\),典型的差卷积形式。

其他三个式子也是类似的,这样我们处理的问题就变成了一个半在线卷积的问题。

使用任意模数 NTT 可以做到 \(O(n\log ^2n)\),使用 Karatsuba 算法可以做到 \(O(n^{\log_23})\),均可通过此题。

Day1 T3 Passport

你可以在第 \(i\) 个国家消耗 \(1\) 的代价获得一个可以到达 \([L_i,R_i]\) 国家的通行证 \(L_i\leqslant i\leqslant R_i\),\(Q\) 次询问,问初始在第 \(X_i\) 个国家,至少需要消耗多少的代价才能到达任何国家。

由于 \(L_i\leqslant i\leqslant R_i\),所以只需要能够到达 \(1\) 和 \(N\) 就可以到达任何节点。

所以不难得到最终的行走方案是先一起走一段路,然后分叉分别走向 \(1\) 和 \(N\)。

例如考虑只走向 \(1\) 的情况,设 \(f_i\) 为从第 \(i\) 个节点走到 \(1\) 至少要几步,则可以得到转移 \(f_i=\min\limits_{j=L_i}^{R_i}f_j+1\),使用 Dijkstra 优化转移,用线段树合并优化建边。

时间复杂度 \(O(n\log^2n)\)。

Day2 T1 belt conveyor

钦定 0 号节点为根。

如果我们在一个点放了物品,它可能会出现在这个点的父亲,这个点或这个点的儿子中,也就是会影响到 3 行。

这启发我们按照深度 \(\mod 3\) 的余数将所有的点分成三组,每一次将物品放在一组上,这样除了交会在同一父亲,否则物品与物品互不影响。

考虑对于每一个点,查询物品所在的地方:

  1. 如果仍在自己这里,它的所有边都指向它,至少确定 \(1\) 条。
  2. 如果在孩子里,它与孩子之间的连边指向孩子,确定 \(1\) 条。
  3. 否则,物品在父亲那里,它与父亲之间的连边指向父亲,确定 \(1\) 条。

也就意味着,我们有多少个物品,我们就至少确定了多少条边。所以我们贪心的选择最大的那一组放物品,这样每一次至少可以将规模减少 \(\dfrac{1}{3}\)。

但是考虑到有的点周围的边都确定了,这样我们在这个点放物品并不能再确定边。所以我们将周围有边没有确定的点权值设为 \(1\),否则设为 \(0\),每一次选择权值最大的一组。

对于已经确定的边,我们可以通过调整方向使得其不影响后面的变化。

每一次规模减少到 \(\dfrac{2}{3}\),发现就是需要大约 30 次。

Day2 T2 council

有 \(N\) 个议员和 \(M\) 个议题,每个人都对每个议题持支持或反对的态度,要选择一个主席和副主席,对于每一个议题,如果除两位主席外支持的人数不小于 \(\left\lfloor\dfrac{N}{2}\right\rfloor\),这个议题就会通过,问每一个人当主席的时候,最多会通过多少个议题。

发现对于某一个人为主席的时候,只有那些当前是 \(\left\lfloor\dfrac{N}{2}\right\rfloor\) 票的议题才有可能会因为副主席而不被通过,假设这些议题的集合为 \(T\)。

记每一个议员通过的议题构成集合 \(S_i\),则对于每一个 \(i\),要求 \(\max\limits_{i\neq j}(\operatorname{popcount}(T\& S_j))\)。

对于每一个数 \(S_i\),使用前缀和得到他的所有子集,每一个子集对应的答案就是他的 popcount,则最终我们就是要找到一个最大的 popcount,使得存在它的一个子集是有值的。

时间复杂度 \(O(m2^m+nm)\)。

Day2 T3 Mizuyokan 2

维护一个序列,支持单点修改,和查询一个区间最多可以分割成多少块,使得这些块的权值和构成波浪形。

通过调整法可知,必然存在最优解使得每一块较小的长度均为 \(1\)。

考虑对于每一个数 \(i\) 维护出 \(f_i\) 表示最小的 \(f_i\),使得 \(S=\sum\limits_{j=i}^{f_i}a_j\),满足 \(S>a_{i-1}\) 且 \(S>a_{f_i+1}\),可以证明 \(f_i\) 最多是 \(O(\log V)\) 的。

然后我们维护出 \(g_i\) 表示 \(\min\limits_{j=i+2}f_j\),则答案可以抽象成若干次跳 \(g_i\) 的过程,通过上面的结论可以知道,\(g_i\) 也是 \(O(\log V)\) 量级的。

使用线段树维护跳的过程即可,时间复杂度 \(O(n\log n\log V)\)。

Day3 T1 Chorus

有 \(2N\) 只海狸唱歌,其中有 \(N\) 只唱高音,有 \(N\) 只唱低音,初始给定他们的位置,问至少要调换多少对海狸,才能使得可以将这个 \(2N\) 的序列分成 \(k\) 个子序列,每个子序列都是前 \(\dfrac{len}{2}\) 个为高音,剩下的唱低音。

将 \(AB\) 序列转化成一条折线,遇到一个 \(A\) 就向上走,遇到一个 \(B\) 就向右走。则对于一个满足条件的折线,要至少能找到这样一个序列 \(p_0,p_1,p_2\dots p_k\),其中 \(p_0=0,p_k=N\),要求点 \((p_{i-1},p_i)\) 在折线下方。对于一条不合法折线,它的代价就是和一个满足条件的折线的面积差的最小值。

我们设计状态 \(f_{l,k}\),表示当前处理到 \(p_k=l\) 时的答案。发现转移为 \(f_{r,k+1}=\min(f_{l,k}+S(l,r))\)。

发现 \(S(l,r)\) 具有凸性和包含性,所以 \(k\) 为可以 WQS 二分处理掉,然后发现 \(l\) 维可以斜率优化,复杂度 \(O(n\log V)\)。

Day3 T2 Cookies

有 \(N\) 中饼干,其中第 \(i\) 种有 \(A_i\) 个;现在要把所有的饼干装进盒子,有 \(M\) 种大小的盒子,问至少需要多少个盒子,才能让每个盒子装满且里面的饼干互不相同。

首先考虑如何证明一种盒子方案时可行的,对于固定的盒子方案,必然容量越大的盒子会有越强的限制,因为它要求内部的饼干不互相同,考虑将所有的盒子从大到小排序,则不难得到如下的式子: \(\sum\limits_{i=1}^Lx_i\le \sum\limits_{i=1}^n\min(A_i,L)\)。不难发现这个式子是存在合法构造的充要条件。

考虑设计DP状态 \(f_{i,j,k}\) 表示,前 \(i\) 个盒子,盒子容积均\(\ge j\),\(\sum\limits_{g=1}^ix_g=k\) 是否可行。

则只会有两种转移:\(f_{i,j,k}\gets f_{i,j+1,k}\),\(f_{i,j,k}\gets f_{i-1,j,k-j}\)。

对于 \(k\) 维可以使用 bitset 优化,发现由于 \(i\times j\leq \sum\limits_{i=1}^na_i=S\),所以本质不同的 \(i,j\) 只有 \(O(S\ln S)\) 对,所以之中的复杂度为 \(O(\dfrac{S^2\ln S}{w})\)。

Day3 T3 Tourism

给定一颗树和一个序列 \(a\),询问需要包含序列上 \([l,r]\) 内所有数对应树上节点的最小连通块的大小。

相当于询问虚树覆盖的节点数。

我们可以强行在这个点集中加入根节点 \(1\),然后减去 \(a_l,a_{l+1}\dots a_r\) 的 \(lca\) 深度 \(-1\) 即可。这样,每一个点的贡献就是一个到根的链。

考虑对 \(r\) 进行扫描线,维护每一个点 \(u\) 最后一次是被哪一个点覆盖,然后把 \((1,a_r)\) 用 \(r\) 覆盖,这个过程很想 LCT 的 access 操作,答案可以使用树状数组维护。

考虑复杂度。这个过程很像颜色段均摊,在每一条重链上进行颜色段均摊即可,复杂度 \(O(n\log^2n)\)。

[Day4 T1 The Last Battle]

Day4 T2 Security Guard

题面比较复杂

我们每一次找到 \(S_i\) 最小的岛,则与它连接的船必然通过这个岛屿交换警卫是最好的。所以可以将这些警卫合并成一个多度的船。

由此,我们可以得到最终的答案就等于 \(\sum\limits_{i=1}^nS_i(deg_i-1)+\max\limits_{i=1}^nS_i\)。

由于这个贡献是对于每一个点来计算的,所以不好拓展到处理边的信息上,但是我们可以改写一下式子:

\(\sum\limits_{i=1}^nS_ideg_i+\max\limits_{i=1}^nS_i-\sum\limits_{i=1}^nS_i\)。

其中后两项适合图形态无关的,而前一项,我们给每一条边 \((u,v)\) 赋权为 \(S_u+S_v\),就是生成树的边权和。

考虑如何处理新加入的边,发现它必然是若干条和全局最小值连接的边,去掉这些边原图构成森林。

我们将每一条无向边 \((u,v)\) 拆成两条有向边 \(u\to v\) 和 \(v\to u\),发现对于 \(k\) 的答案就是 \(k+1\) 棵树最小内向森林的边权和 \(+\sum\limits_{i=1}^nS_i+(k-1)\min\limits_{i=1}^nS_i\)。

使用最小树形图的算法即可,时间复杂度 \(O(m\log m)\)。

Day4 T3 Bitaro's Travel

在数轴上有若干个点,从一个点(不一定是数轴上的点)为起点,每次走向距离当前点最近的点,问要走多长的距离。

记 \(\Delta\) 为当前左边最近的未走到的点和右边最近的未走到的点之间的距离,如果相邻某两次操作方向不同,则 \(\Delta\) 至少翻一倍,所以只会有 \(O(\log V)\) 次转向,二分答案即可,复杂度 \(O(n\log n\log V)\)。

JOISC 2023 纪录的更多相关文章

  1. EntityFramework 7 开发纪录

    博文目录: 暂时开发模式 Code First 具体体现 DbContext 配置 Entity 映射关联配置 Migration 问题纪录(已解决) 之前的一篇博文:EF7 Code First O ...

  2. 个人纪录(初)----配置文件.properties的简单读取

    本文为个人文本纪录. demo:::: 1.创建普通的java项目:这实例项目名字叫properties. 2.创建.properties文件:src目录下创建XX.properties文件,识别&q ...

  3. BASIS--笨办法解决ALV_GRID的列剪切丢失纪录的错误

    最近经常有业务人员问及在ALV_grid输出报表中,选择某一列,点击左键,并点击弹出菜单的复制文本,复制出的文本存在丢失 (纪录不少,但部分纪录的文本丢失).该如何解决呢? 后来跟踪代码发现这个命令没 ...

  4. 消格子时一个很深的bug的修复纪录

    环境: cocos2d-x 2.2.2  jsb   条件:当快速在格子中来回拖拽选取时,会一直在计算指尖和格子的真实区域是否碰撞,   报错:touchMOve时由于不停的调用BOxItem的get ...

  5. Xamarin.Android之转换,呼叫,查看历史纪录

    Xamarin.Android之转换,呼叫,查看历史纪录 E文文章. 功能:能将输入的字母转换成相应的数字.并且能呼叫出去.能查看呼叫的历史纪录. 界面代码如下: <?xml version=& ...

  6. BUG修改纪录

    刚进入现在的公司,接手了一个遗留的项目,BUG频出,最近一个星期都在加班改BUG,身心疲惫,为了 现在,将来不会再被相同BUG困扰,特来纪录一下. 1.数据库设计字段时,对于int等类型最好设置默认值 ...

  7. iOS tableview 静态表布局纪录

    今天使用了tableview静态表布局,纪录如下 1:使用tableview 静态表,必须是UITableViewController 2:Content 中选择 Static Cells 如下图 3 ...

  8. mongoDB文件太大查错纪录

    日志系统,突然从24号之后的都断层了,交易看不见.查了一下问题是MongoDB把硬盘撑爆了,看了下情况: -bash-3.2$ du -h 82M ./log .1G ./db/journal .0K ...

  9. 1630/2023: [Usaco2005 Nov]Ant Counting 数蚂蚁

    2023: [Usaco2005 Nov]Ant Counting 数蚂蚁 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 85  Solved: 40[S ...

  10. 实战小项目BUG纪录

    果然,作为程序员最可爱的女朋友就是各种BUG,解决了你的开发能力和开发效率就会上升到一个新的层次.反之,在你面对BUG的时候,如果轻易的就放弃了,你也就失去了一次自我成长的机会.学习就是这样的,我们有 ...

随机推荐

  1. Linux-关机重启和注销

  2. [转帖]拯救关键业务上线:DBA 的惊魂24小时

    一个电话,打破深夜的宁静 9月20日晚上10点 刚完成外地一个重点项目为期2周的现场支持,从机场回家的路上,一阵急促的铃声惊醒了出租车上昏昏欲睡的我,多年的工作经验告诉我这么晚来电一定是出事了,接起电 ...

  3. [转帖]利用Python调用outlook自动发送邮件

    ↓↓↓欢迎关注我的公众号,在这里有数据相关技术经验的优质原创文章↓↓↓ 使用Python发送邮件有两种方式,一种是使用smtp调用邮箱的smtp服务器,另一种是直接调用程序直接发送邮件.而在outlo ...

  4. Kafka学习之四_Grafana监控相关的学习

    Kafka学习之四_Grafana监控相关的学习 背景 想一并学习一下kafaka的监控. 又重新开始学习grafana了: 下载地址: https://grafana.com/grafana/dow ...

  5. [转帖]Windows版本vcenter server6.0的SSO密码重置

    Windows版本的SSO重置与vCenter Server Appliance的重置类似 登录vcenter服务器,打开DOS窗口,输入 cd c:\Program Files\VMware\vCe ...

  6. [转帖]iptables命令详解和举例(完整版)

    1.防火墙概述 防火墙,其实说白了讲,就是用于实现Linux下访问控制的功能的,它分为硬件的或者软件的防火墙两种.无论是在哪个网络中,防火墙工作的地方一定是在网络的边缘.而我们的任务就是需要去定义到底 ...

  7. JRC Flink流作业调优指南

    # 作者:京东物流 康琪 本文综合Apache Flink原理与京东实时计算平台(JRC)的背景,详细讲述了大规模Flink流作业的调优方法.通过阅读本文,读者可了解Flink流作业的通用调优措施,并 ...

  8. echarts饼图中央自定义文字

    var option = { tooltip: { trigger: 'item' }, legend: { top: '5%', left: 'center' }, //中央自定义文字 title: ...

  9. 把Unity的日志保存到文件中

    Unity的日志事件 Unity提供了两个日志回调API,这两个回调函数的参数都是一样的,通过这个API可以在真机上把Debug.Log/LogWarning/LogError 日志输出到文件中保存, ...

  10. 设计模式学习-使用go实现组合模式

    组合模式 定义 适用范围 优点 缺点 代码实现 参考 组合模式 定义 组合模式(Composite),将对象组合成树形结构以表示'部分-整体'的层次关系.组合模式使得用户对单个对象和组合对象的使用具有 ...