2017 Multi-University Training Contest 5 solutions BY 吉如一

发表回复

出题时难度安排大概是:

Easy: 06,08,1106,08,11。

Medium-Easy:01,0901,09。

Medium:02,04,0702,04,07。

Medium-Hard:03,05,1003,05,10。

感觉全放中档题无法阻止多人多机 AK 的铁蹄啊..

1001 Rikka with Candies

考虑预处理出所有 kk 的答案,问题相当于一个模 22 意义下的 \text{mod}mod 卷积,即给出数组 A,BA,B,将 A_i \times B_jA​i​​×B​j​​ 累加到 w_{i\ \text{mod}\ j}w​i mod j​​ 上。

因为 i\ \text{mod}\ j=i-j\lfloor \frac{i}{j} \rfloori mod j=i−j⌊​j​​i​​⌋,因此可以枚举 jj 和 k=\lfloor \frac{i}{j} \rfloork=⌊​j​​i​​⌋。这时相当与把 AA 中区间 [kj,(k+1)j)[kj,(k+1)j)中的所有数依次加到 ww 的 [0,j)[0,j) 区间上。

因为模 22 意义下的加法可以用异或实现,因此可以用压位来优化,这样时间复杂度为 \sum_{i=1}^n \frac{n}{i} \times (32+\frac{i}{32})∑​i=1​n​​​i​​n​​×(32+​32​​i​​),这约是 \frac{n^2}{32}​32​​n​2​​​​。

注意因为 bitset 不支持提取区间操作,因此需要手写压位。如果不手写也可以用分块的方法来达到同样的复杂度但是常数比手写 bitset 大很多,可能需要一些常数优化才能通过时限。

1002 Rikka with String

如果没有反对称串的限制,直接求一个长度为 LL 的 0101 串满足所有给定串都出现过,那么是一个经典的 AC 自动机的问题,状态 f[i][j][S]f[i][j][S] 表示长度为 ii,目前在 AC 自动机的节点 jj 上,已经出现的字符串集合为 SS 的方案数,然后直接转移即可,时间复杂度 O(2^nL\sum |s|)O(2​n​​L∑∣s∣)。

然后如果不考虑有串跨越中轴线,那么可以预处理所有正串的 AC 自动机和所有反串(即原串左右翻转)的 AC 自动机,然后从中间向两边 DP,每一次枚举右侧下一个字符是 00 还是 11,那么另一侧一定是另外一个字符。状态 f[i][j][k][S]f[i][j][k][S] 表示长度为 2i2i,目前右半边在正串 AC 自动机的节点 jj 上,左半边的反串在反串 AC 自动机的节点 kk 上,已经出现的字符串集合为 SS 的方案数,然后直接转移,时间复杂度 O(2^nL(\sum |s|)^2)O(2​n​​L(∑∣s∣)​2​​)。

现在考虑有串跨越中轴线,可以先爆枚从中间开始左右各 \max|s|-1max∣s∣−1 个字符,统计出哪些串以及出现了。对于之后左右扩展出去的字符来说,肯定没有经过的它们的字符串跨越中轴线,因此可以以爆枚的结果为 DP 的初始值,从第 \max|s|max∣s∣ 个字符开始 DP。

时间复杂度 O(2^nL(\sum |s|)^2+\max|s|2^{\max|s|})O(2​n​​L(∑∣s∣)​2​​+max∣s∣2​max∣s∣​​)。

这儿的 DP 直接把数组开满然后转移,实际上有用的状态数不会这么多,有用的状态应该是 O(2^nL\max |s|\sum |s|)O(2​n​​Lmax∣s∣∑∣s∣) 的。

1003 Rikka with Sequence

这是一道可持久化平衡树的题,在执行第二类操作的时候,要注意因为赋值是从左到右循环的,因此之前已经改变了的值会影响到后面的值,例如在 A_lA​l​​ 变成 A_{l-k}A​l−k​​ 后,A_{l+k}A​l+k​​ 也会变成 A_{l-k}A​l−k​​ 的值(如果 $l+k 
\leq r$)。

因此我们提取出 [l-k,l-1][l−k,l−1] 的区间,然后把它重复拼接 \frac{r-l+1}{k}​k​​r−l+1​​ 次,最后再接上多出来的一段,即区间 [l-K,l-K-1+(r-l+1)\ \text{mod}][l−K,l−K−1+(r−l+1) mod],就是修改后的区间 [l,r][l,r],插入平衡树中即可。

关键在于怎么把一棵平衡树 TT 自己拼接 KK 次,可以使用快速幂的方法,这样一次操作需要进行 O(\log n)O(logn) 次平衡树合并,复杂度为 O(\log^2 n)O(log​2​​n),也可以新建若干个空节点(即不代表序列中实际位置的节点,只是拿来辅助合并),然后把 TT 作为叶子节点连上去。因为平衡树是可持久化的,即一个节点的左右儿子可以是同一个节点,因此只需要新建 O(\log K)O(logK) 个节点就可以了,这样单次的时间复杂度是 O(\log n)O(logn) 的。

然而这两种做法的空间复杂度都过高了。本来我没有打算卡空间但是因为杭电不能支持过大的空间而把数据范围放小又卡不掉暴力,因此只能再加上一步对空间的优化,即需要写内存回收。

但是在可持久化数据结构上写内存回收是一件比较复杂的事情,特别是在这题中,儿子指针的连接情况可能会非常复杂。因此需要对每一个节点记一个引用计数,记有多少个节点的孩子指针以及根节点指针指向它,当一个节点的引用计数变为 00 的时候,表示这个点已经没用了,这个时候把这个点删掉,并修改它两个孩子的引用计数并继续递归。

这样时间复杂度不变,第一种做法的空间复杂度降到了 O(n)O(n),可以通过此题。(第二种做法感觉空间复杂度还是 O(n \log n)O(nlogn) 的,可能常数小了很多,验题的时候也可以通过。)

比赛中看到了更方便的做法,直接每 O(\sqrt m)O(√​m​​​) 次操作重建一下整棵树,然后把没用的空间给清理掉,这样的空间复杂度就降到 O(n+\sqrt m \log n)O(n+√​m​​​logn) 了。

1004 Rikka with Rock-paper-scissors

使用莫比乌斯反演可以进行如下的推导,其中 i,ji,j 分别为双方胜利的局数,这儿没有详细考虑 i,j=0i,j=0 时的特殊情况,实际情况下要特判。
\begin{align*}
\text{Ans}&=3^n \sum_{i=0}^n \sum_{j=0}^{n-i} \binom{n}{i} \binom{n-i}{j} (i,j) \
&=3^n \sum_{d=1}^n \phi(d) \sum_{i=0}^{\frac{n}{d}} \sum_{j=0}^{\frac{n}{d}-i} \binom{n}{id} \binom{n-id}{jd}
\end{align*}
其中第一个求和可以爆枚 dd,后面两个求和是一个 \frac{n}{d} \times \frac{n}{d}​d​​n​​×​d​​n​​ 的卷积,可以用 FFT 进行优化,时间复杂度为 \sum_{i=1}^n O(\frac{n}{i} \log n)=O(n \log^2 n)∑​i=1​n​​O(​i​​n​​logn)=O(nlog​2​​n)。

1005 Rikka with Terrorist

问题相当于平面中有若干障碍点,询问以某一个点为四个角之一的不包含障碍点的矩形有多少个。

对每一组询问,维护数组 U,DU,D,U_iU​i​​ 表示所有在询问点上方的障碍点中,横坐标为 ii 的纵坐标最小值,D_iD​i​​ 表示所有在询问点下方的障碍点中,横坐标在 ii 的纵坐标最大值。那么枚举矩形横坐标范围的另一端 jj,满足条件的矩形有 \min_{k \in [i,j]} U_k-\max_{k \in [i,j]} D_k -1min​k∈[i,j]​​U​k​​−max​k∈[i,j]​​D​k​​−1 个。

离线,按照纵坐标从小到大枚举询问,因为 UU 和 DD 只会修改 O(K)O(K) 次,所以可以用线段树维护。之后要考虑的就是求 \sum_{j=1}^n \min_{k \in [i,j]} U_k∑​j=1​n​​min​k∈[i,j]​​U​k​​ 和 \sum_{j=1}^n \max_{k \in [i,j]} D_k∑​j=1​n​​max​k∈[i,j]​​D​k​​。这个是李超树的经典问题,可以在 O(n \log^2 n)O(nlog​2​​n) 的时间复杂度内解决。

总的时间复杂度为 O(n \log^2 n)O(nlog​2​​n),这儿假设 n,m,K,qn,m,K,q 都是 O(n)O(n) 的。

1006 Rikka with Graph

考虑贪心地一条一条边添加进去。

当 m \leq n-1m≤n−1 时,我们需要最小化距离为 nn 的点对数,所以肯定是连出一个大小为 m+1m+1 的联通块,剩下的点都是孤立点。在这个联通块中,为了最小化内部的距离和,肯定是连成一个菊花的形状,即一个点和剩下所有点直接相邻。

当 m > n-1m>n−1 时,肯定先用最开始 n-1n−1 条边连成一个菊花,这时任意两点之间距离的最大值是 22。因此剩下的每一条边唯一的作用就是将一对点的距离缩减为 11。

这样我们就能知道了最终图的形状了,稍加计算就能得到答案。要注意 mm 有可能大于 \frac{n(n-1)}{2}​2​​n(n−1)​​。

1007 Rikka with Match

一个简单的 DP 套 DP。考虑怎么计算删除一个边集后的最大匹配,这是一个简单的树形 DP,f[i]f[i] 表示 ii 的子树中,选了第 ii 个节点的最大匹配,g[i]g[i] 表示不选的最大匹配。

不难发现有 0 \leq f[i]-g[i] \leq 10≤f[i]−g[i]≤1,因此 DP 的状态只有 2n2n 个,因此在 DP 套 DP 中以这个为状态。w[i][j][k]w[i][j][k] 表示考虑 ii 的子树,f[i]\ \text{mod}\ m=jf[i] mod m=j 且 f[i]-g[i]=kf[i]−g[i]=k 的方案数然后暴力进行转移。

暴力转移的话合并两个子树的枚举量是 \min(\text{size}_i,m) \times \min(\text{size}_j,m)min(size​i​​,m)×min(size​j​​,m) 的,这样的树形 DP 看起来是 O(nm^2)O(nm​2​​) 的但是实际上是 O(nm)O(nm) 的,具体证明可以看我之前出的一道 BC 题。

1008 Rikka with Subset

签到题,大致的思想就是反过来的背包。

如果 B_iB​i​​ 是 BB 数组中除了 B_0B​0​​ 以外第一个值不为 00 的位置,那么显然 ii 就是 AA 中的最小数。

现在需要求出删掉 ii 后的 BB 数组,过程大概是反向的背包,即从小到大让 B_j-=B_{j-i}B​j​​−=B​j−i​​。

时间复杂度 O(nm)O(nm)。

1009 Rikka with Number

首先转化成计算小于等于 NN 的好数有多少个。因为 n^n<(n+1)^nn​n​​<(n+1)​n​​,而对于 nn 进制下的任何一个好数 KK,都有 n^{n-1}<K<n^nn​n−1​​<K<n​n​​,所以每一个进制下好数的大小区间是不相交的。

不难发现 dd 进制下好数的个数为 d!-(d-1)!d!−(d−1)!,因此我们只需要计算在临界的 dd 进制下,好数的个数就可以了。关于临界的 dd,可以用对数估计位数得到。

求 dd 进制下小于等于 NN 的好数个数,先讲 NN 转化成 dd 进制,然后做一个类似康托展开的过程就可以了,因为数据范围很小,所以每一步操作都可以暴力进行。

时间复杂度 O(|R|^2)O(∣R∣​2​​)。

1010 Rikka with K-Match

应该是一个经典的 Idea 了。令 w_iw​i​​ 为匹配数为 ii 时的最小匹配,那么因为匹配是一个费用流问题,所以一定有 w_{i+1}-w_{i} \geq w_{i}-w_{i-1}w​i+1​​−w​i​​≥w​i​​−w​i−1​​。

考虑把 w_iw​i​​ 看成平面上的点 (i,w_i)(i,w​i​​),那么显然所有点都分布在一个下凸壳上,因此肯定存在一个斜率 dd,使得这个斜率的直线与下凸壳的切点恰好为 (K,w_K)(K,w​K​​),即 (K,w_K)(K,w​K​​) 为 w_i-idw​i​​−id 最小的点,这相当于把边权减去 dd 后的最小匹配。

因此可以二分斜率 dd,然后求出边权全部减去 dd 后的最小匹配的值以及最小匹配中有多少条边,根据最小匹配中的边数和 KK 的大小关系来决定二分的方向。这样问题就转化成了求 O(\log n)O(logn) 次网格图最大匹配。这是一个轮廓线 DP 的经典问题,可以在 O(nm2^m)O(nm2​m​​) 内解决。

因此总的时间复杂度为 O(nm2^m\log n)O(nm2​m​​logn)。

要注意的是二分上界不能设为 10^910​9​​ 级别,考虑一条 11 和 10^910​9​​ 交错的链,那么在最后一次增广的时候所有的 11 都会变成 10^910​9​​,因此二分上界应该是 10^9 \times \frac{nm}{2}10​9​​×​2​​nm​​,标程把上界设为了 10^{14}10​14​​,DP 时刚好不会爆 long long。

1011 Rikka with Competition

临时加的签到题。把 a_ia​i​​ 从大到小排序,那么第 ii 强人要获胜,最优情况下是最强的人输给了第二强的人,第二强的人输给了第三强的人,以此类推。因此只需要判断排序后 \max_{j<i} (a_j-a_{j+1})max​j<i​​(a​j​​−a​j+1​​) 和 KK 的大小关系即可。

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

2017 Multi-University Training Contest 5 solutions BY 吉如一相关推荐

  1. 2017 Multi-University Training Contest 4 solutions BY 陈松杨

    2017 Multi-University Training Contest 4 solutions BY 陈松杨 发表回复 1001. Big Integer 如果知道k-1k−1个数的个数c_1, ...

  2. 2017 Multi-University Training Contest 1 solutions BY 北京航空航天大学

    转自 http://bestcoder.hdu.edu.cn/blog/ 1001. Add More Zero 答案就是 ⌊log10(2m−1)⌋\left \lfloor \log_{10}(2 ...

  3. HUST-2015 Multi-University Training Contest 9

    2015 Multi-University Training Contest 9 solutions BY xudyh 1001.Expression 记dp_{l,r}dp​l,r​​表示l,rl, ...

  4. HDU 6091 - Rikka with Match | 2017 Multi-University Training Contest 5

    思路来自 某FXXL 不过复杂度咋算的.. /* HDU 6091 - Rikka with Match [ 树形DP ] | 2017 Multi-University Training Conte ...

  5. HDU 6051 - If the starlight never fade | 2017 Multi-University Training Contest 2

    /* HDU 6051 - If the starlight never fade [ 原根,欧拉函数 ] | 2017 Multi-University Training Contest 2 题意: ...

  6. HDU 6058 - Kanade's sum | 2017 Multi-University Training Contest 3

    /* HDU 6058 - Kanade's sum [ 思维,链表 ] | 2017 Multi-University Training Contest 3 题意:给出排列 a[N],求所有区间的第 ...

  7. 2017 Multi-University Training Contest - Team 3 Kanade's sum hd6058

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6058 题目: Kanade's sum Time Limit: 4000/2000 MS (J ...

  8. 2017 Multi-University Training Contest - Team 1

    2017 Multi-University Training Contest - Team 1 01     签到的 #include<bits/stdc++.h> using names ...

  9. 2017 Multi-University Training Contest - Team 7:1003. Color the chessboard(...)

    其他题目题解: 2017 Multi-University Training Contest - Team 7:1005. Euler theorem 2017 Multi-University Tr ...

  10. 2017 Multi-University Training Contest - Team 7:1002. Build a tree(递归)

    其他题目题解: 2017 Multi-University Training Contest - Team 7:1005. Euler theorem 2017 Multi-University Tr ...

最新文章

  1. 【HeadFirst设计模式】8.模板方法模式
  2. 原型设计工具【收集转帖】
  3. BLE-NRF51822教程13-连接时触发配对
  4. luogu P3786 萃香抱西瓜
  5. Vagrant+VirtualBox版本的坑
  6. 知乎大V推荐!面试官6个灵魂拷问,原理+实战+视频+源码
  7. 信息学奥赛一本通 1153:绝对素数
  8. SpaceEmacs Rocks Day8 学习笔记
  9. linux ssh非交互脚本,Linux expect非交互式执行脚本
  10. (第十章)多表查询之in,exitst
  11. zmodem transfer cancled by remote side 解决办法
  12. EPUB和PDF的区别,有什么好用的安卓epub阅读器
  13. 七牛云图片服务器搭建,对接
  14. 落花已去,相思成冢。十月的杜鹃雨,下得纷纷扬扬。我走在花瓣雨下,回忆我们曾经的甜蜜温馨,一回首,一抬头,仿佛你就在灯火阑珊处。那些掉落在地上的杜鹃,成了相思的墓,也许是为了祭奠我们曾经的美好。 杜鹃
  15. python中for循环的代码_Python中的九九乘法表(for循环)
  16. html中字段间距代码,css调字体大小代码 css字与字之间的间距怎么调
  17. 十大经典排序算法(图解与代码)——冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序、基数排序(Python and Java)
  18. 用友企业空间 - http://upesn.com
  19. android 选择联系人右侧首字母显示
  20. 看山还是山,看水还是水

热门文章

  1. flash做动画教程(基础篇)
  2. 配置各个连接oracle客户端
  3. Alexa | Alexa Auto SDK 概述
  4. java 中常见的文件上传方式_java中如何上传文件
  5. c语言贪吃蛇作业报告,贪吃蛇设计报告
  6. java中的Properties配置文件
  7. 自己动手写开源爬虫框架 Slit
  8. 万特电能表接线仿真系统 软件_电工技能——分享一款超实用的电工仿真教学接线Flash动画软件...
  9. 用计算机代码怎么表白,IT男专用表白程序
  10. 【板栗糖GIS】global mapper 如何通过dsm批量制作贴地等高线