浙江财经大学第十四届程序设计竞赛题解
Posted Fighting Heart
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浙江财经大学第十四届程序设计竞赛题解相关的知识,希望对你有一定的参考价值。
【题面pdf下载】链接: https://pan.baidu.com/s/1Eb16fHtNYMLrRk9QnXWa-g 密码: dwn8
【现场赛排名】链接: https://pan.baidu.com/s/1jfzH6-7BoPhEjnijGQK53w 密码: y669
感谢各位大佬的参赛。
由于命题人水平不高,而且之前没有命题经验,又是第一次把题目放到外网,所以可能会有数据不严谨的情况出现;也有可能出题人对问题理解不深刻,没想到最优解。如果发现了题目中的各种问题,可以在各种ACM QQ群(例如ACFun、ACM贴吧群、牛客网群)进行交流学习,也可以在这个博客留言。
有做的不好的地方,希望各位大佬多多包涵,批评指正。
Problem A. A Sad Story
先考虑求区间最大值和是最小值的情况:
证明:满足最大值和是最小值时的多个序列中,必定有一种序列的最大值在序列两端。
一个序列中拿出其最大值,对剩下的所有数的任意排列中,插入这个最大值。
当这个最大值排在两端时,原序列区间最大值和加上这最大值。
当这个最大值不在两端时,原序列区间最大值和加上这最大值,以及加上因这最大值加入而改变的区间最大值的差值(此时区间最大值一定不小于原区间最大值)。
例子:
$K$ 为 $3$ 。
$1$ $5$ $3$ $2$ $4$ 加入 $6$ 。
$1$ $5$ $3$ $2$ $4$ $6$ 为 $5 + 5 + 4 + 6$
$1$ $5$ $3$ $2$ $6$ $4$ 为 $5 + 5 + 6 + 6$
不在两端的最大值多了改变大小的区间最大值 $6 - 4$
这个结论对任意排列的序列都成立,因此所有区间最大值和是最小值的序列中,存在最大值在序列两端的序列。
可得:
当序列为 V 字型时,一定是区间最大值和是最小值。
同理可得:
当序列为 Λ 字型时,一定是区间最小值和是最大值。
综合得:
当序列为单调序列时,一定是区间最大值减最小值和的最小值。
单组数据时间复杂度 $O(NlogN)$。
Problem B. Bazinga
如果 $x$ 和 $k$ 互质,那么 $x$ mod $k$ 和 $k$ 也互质。
以及 $(x + k * 1) * (x + k * 2) * (x + k * 3) * ... * (x + k * p) \\equiv x^p$ (mod $k$) 。
把 $[1, k-1]$ 中与 $k$ 互质的数相乘,得到一个循环节对答案的贡献,再对其在 $[l, r]$ 中出现的次数做快速幂计算。
再把之前 $[l, r]$ 不在循环节内的数暴力跑一遍乘进答案。
注意点:
- $k$ 为 $1$ 时,答案为 $0$。
单组数据时间复杂度 $O(K)$。
Problem C. Collect Jewel
性质1(虽然这个性质对解题好像没啥用):在最优解中,每一个士兵在行走过程中,身上的价值是不可能变负的。
性质2(虽然这个性质对解题好像也没啥用):在最优解中,一个士兵的路线终点,不可能是另一个士兵路线的起点。
性质3(虽然这个性质对解题好像又没啥用):派出 $K$ 个士兵一定能得到最优解。
正题:
这是一个很容易察觉到的最 x 费用最大流问题。
由于每个节点能获得至多 $1$ 次价值,第二个人再次走过这个节点,就无法获得这个价值,因此需要拆点,每一个节点 $i$ 拆成两个 $2i+1$ 和 $2i+2$,建立如下边 $(2i+1,2i+2,1,V_i)$ 以及 $(2i+1,2i+2,inf,0)$。
对于原图中每一条有向边 $\\left< x,y \\right> $,建立如下边 $(2x+2,2y+1,inf,-C_i)$。
建立超级原点$S$,建立$(S, 2i+1, inf, 0)$。
建立超级汇点$T$,建立$(2i+2,T,inf,0)$。
控制一下 $S$ 出去的流量最多为 $K$,跑一个最大费用最大流即可。可以把每条边权取反之后求最小费用最大流,其中最小费用的绝对值就是答案。
注意:题目中数据范围保证了 $U_i<V_i$ ,因此图是有向无环图,建完图的网络是不存在负环的。
单组数据时间复杂度 $O(min(K,N)NM)$。
这题如果不保证 $U_i<V_i$,就需要消负圈,如果有大佬会搞,望不吝赐教,看到网上很多都是一句话带过,例如“强制把负圈满流”,zkw 博客好像也没给出代码,还发现了一个题 POJ 2175。
Problem D. Disport with Jelly
可以这样考虑:问题等价于有两堆石头,第一堆有 $K-L$ 个,第二堆有 $R-K$ 个,每人每次可以从任意一堆中取任意个,取走最后一个石头的人算赢。这就是经典的 Nim 取子游戏,看两堆石头异或值即可。由于这里只有两堆石头,也可以判断两堆石头数量是否相等。
单组数据时间复杂度 $O(1)$。
Problem E. Easygoing Single Tune Circulation
简单地说题意就是,一个字典库有 $N$ 个字符串,每个字符串中无重复字符,每个字符串以输入作为最小周期无限循环。
有 $Q$ 次询问,每次询问一个字符串是否是 $N$ 个串中其中一个的子串。
由于字典库中每个字符串都是无限循环的,所以对于每个询问的串,也必须是循环的,不循环的就无解。例如[abcd],[aba],[abab]都被认为是循环的,第一个循环节是本身,第二,三两个循环节均为[ab];而[abb],[abcdc]被认为不循环。
也就是说循环节要么没有,要么就是从第 $0$ 个字符开始到第一个出现重复字符的前一个位置结束。(因为 $S_i$ 中无重复字符)
【1】对于每一个询问,我们首先可以判定一下这个询问串是否是字典库中某个串两倍的子串。如果找到就有解。这里可以搞个广义 SAM,每个子串都必然包含在 SAM 的某个状态里。
【2】如果没有找到,就需要去寻找这次询问的串的循环节是否可以由字典库中某个串通过循环同构得到。可以将每一个 $S_i$ 的最小表示法插入字典树,询问的时候,可以把循环节也转成最小表示法,然后去字典树中找一找。
下面这种做法也放过去了:
把每一个 $S_i$ 及其循环同构的串都插入到字典树中,然后两种都可以查询了。
各种 hash 算法不知道能不能过,造数据的时候卡了少数常见 base 和 mod,然后卡了一些双 hash 超时。
Problem F. Formula One
枚举两辆车 $i$ 和 $j$,计算这两辆车的超车次数。
两辆车第一次相遇的时候,必然是快车比慢车多开了一圈,依据这个性质,可以计算出辆车第一次相遇的时间。两车相邻两次相遇的时间间隔是不会变的。
相遇一次超车一次,刚好在停止的时候相遇就不算超车。
公式 $\\left\\lfloor \\frac { P\\times \\left| { A }_{ i }-{ A }_{ j } \\right| -1 }{ { A }_{ i }\\times { A }_{ j } } \\right\\rfloor$
其中 $R$ 是可以不用的。
注意点:
- 精度问题,最好用整型计算
- $P$ 时刻刚好相遇不算超车
单组数据时间复杂度 $O(n^2)$。
Problem G. Get the Highest Score
首先有两个贪心思想:
- 连续的一段 $-1$ 肯定需要填同一种数。
- 连续的一段 $-1$ 的左边和右边是同一种数字,那么这段 $-1$ 就填那个数。
上述两步填完后,按照题目中的方法压缩数组。
然后这样考虑:最后肯定有一段数字是相同的,也就是枚举位置 $x$,让 $val[1,n]= max(val[1, x] + (n-x)^2)$ 最大,枚举过程中保证 $[x+1,n]$ 可以变成相同的数字。$val[1, x]$ 的最大值也是如此求解。
因此从左到右 dp ,记录前缀能获得的最大分数。可以发现,压缩后的数组,最后一段相同的不会超过三小段。
单组数据时间复杂度 $O(n)$。
Problem H. Hero
按照 $A$ 是小于 $0$,还是等于 $0$,还是大于 $0$,将物品分成三类。
在同一类中:
以 $B$ 从小到大排序。先考虑 $B_{x}$ 左边对其的影响,会发现有决策单调性(证明如下),右边用同样的方法处理。
$B_{i} < B_{j} < B_{y} < B_{x} < B_{z}$
若 $|A_{i}| \\ge |A_{j}|$,$|A_{j}|$ 就可以不考虑,剩下就是单调递增的 $|A|$ 。
证明:
当 $B_{x}$ 在 $i$ 取到最优解。
$|A_{i}|*|A_{x}|*(B_{x}-B_{i})^2 > |A_{j}|*|A_{x}|*(B_{x}-B_{j})^2 $ 得
$B_{x}-B_{j} < \\frac { \\left( { B }_{ j }-{ B }_{ i } \\right) \\times \\sqrt { |{ A }_{ i }| } \\times \\left( \\sqrt { |{ A }_{ j }| } +\\sqrt { |{ A }_{ i }| } \\right) }{ |{ A }_{ j }|-|{ A }_{ i }| } $
$B_{x}-B_{j} > 0 > \\frac { \\left( { B }_{ j }-{ B }_{ i } \\right) \\times \\sqrt { |{ A }_{ i }| } \\times \\left( \\sqrt { |{ A }_{ j }| } -\\sqrt { |{ A }_{ i }| } \\right) }{ |{ A }_{ j }|-|{ A }_{ i }| }$
$0 < B_{y}-B_{j} < B_{x}-B_{j} < \\frac { \\left( { B }_{ j }-{ B }_{ i } \\right) \\times \\sqrt { |{ A }_{ i }| } \\times \\left( \\sqrt { |{ A }_{ j }| } +\\sqrt { |{ A }_{ i }| } \\right) }{ |{ A }_{ j }|-|{ A }_{ i }| } $
因此 $B_{y}$ 一定不在 $j$ 取到最优解,故 $B_{y}$ 在 $i$ 或之前取到最优解。
当 $B_{x}$ 在 $j$ 取到最优解。
$|A_{i}|*|A_{x}|*(B_{x}-B_{i})^2 < |A_{j}|*|A_{x}|*(B_{x}-B_{j})^2 $ 得
$B_{x}-B_{j} > \\frac { \\left( { B }_{ j }-{ B }_{ i } \\right) \\times \\sqrt { |{ A }_{ i }| } \\times \\left( \\sqrt { |{ A }_{ j }| } +\\sqrt { |{ A }_{ i }| } \\right) }{ |{ A }_{ j }|-|{ A }_{ i }| } $
$B_{x}-B_{j} < \\frac { \\left( { B }_{ j }-{ B }_{ i } \\right) \\times \\sqrt { |{ A }_{ i }| } \\times \\left( \\sqrt { |{ A }_{ j }| } -\\sqrt { |{ A }_{ i }| } \\right) }{ |{ A }_{ j }|-|{ A }_{ i }| } < 0$ 不用考虑
$B_{z}-B_{j} > B_{x}-B_{j} > \\frac { \\left( { B }_{ j }-{ B }_{ i } \\right) \\times \\sqrt { |{ A }_{ i }| } \\times \\left( \\sqrt { |{ A }_{ j }| } +\\sqrt { |{ A }_{ i }| } \\right) }{ |{ A }_{ j }|-|{ A }_{ i }| } $
因此 $B_{z}$ 一定不在 $i$ 取到最优解,故 $B_{z}$ 在 $j$ 或之后取到最优解。
剩下就用决策单调性就可以来做了。
单组数据时间复杂度 $O(nlogn)$。
Problem I. Interesting Set
这题思路很直白,先求出 $N$ 是第几个,可以用很多方法求出是第 $P$ 个,然后判断下 $P+K$ 是否存在,存在则求出第 $P+K$ 个是谁。算的时候杨辉三角打个表,算一算方案数这种就可以了,也可以用数位 dp 的思路来做。
单组数据时间复杂度 $O(log(10^{18}))$。
Problem J. Journey
要求经过每个点恰好一次,每条边恰好一次,只有一条链是满足要求的,也就是只要判断给出的图是否是一条链即可。
注意点:
- 一条链加一个简单环的图
- 一个节点,没有边的图
- 清空数组用了 memset 会超时
单组数据时间复杂度 $O(n+m)$。
Problem K. Keep Danding
不妨把一个询问拆成两个,计算出区间长度小于等于 $R$ 的方案数,以及小于等于 $L-1$ 的方案数,相减即可得到答案。
下面说明区间长度小于等于 $K$ 的方案数:
首先预处理出 $f[i]$,表示 $i$ 位置最远能到达 $f[i]$ 位置,保证区间 $[i,f[i]]$ 无重复元素,容易发现 $f[i]$ 是非递减的。
令 $g[i] = f[i] - i + 1$,表示区间长度。
对于一次询问,我们可以把 $[L, R]$ 拆成两段来计算方案数。
$[L, R - K]$: 考虑每一个位置作为区间左端点的方案数,就是求这段区间上 $g[i]$ 小于等于 $K$ 的数字的和,主席树可以单 log 高效求解。线段树上每个节点排个序,每个节点二分这种双 log 做法在现场赛也是允许通过的。
$[R-K+1, R]$: 这个部分比较经典,二分 $f$ 数组。
Problem L. Limitless Matrix
这题绝对 不 是暴力!
当 $|K|$ 为素数或 $1$ 或 $0$ 时不可能有解。
当 $N$ 为 $1$ 时不可能有解。
当 $N$ 为 $2$ 时,只有 $K$ 为平方数有解, $2 \\times 2$ 矩阵每个元素都是 $ \\sqrt K$ 。
当 $N$ 为 $3$ 时,只有 $K$ 为立方数有解(证明如下), $3 \\times 3$ 矩阵每个元素都是 $ \\sqrt[3] K$ (也可以用其他的方法凑,不过 $ \\sqrt[3] K$ 最方便)。
证明:$N$ 为 $3$ 时情况。
$\\left[ \\begin{matrix} a & b & c \\\\ d & e & f \\\\ g & h & i \\end{matrix} \\right] $
$(a \\times b \\times c) \\times (d \\times e \\times f) \\times (g \\times h \\times i) = K^3 = (a \\times e \\times i) \\times (b \\times e \\times h) \\times (c \\times e \\times g)$
$d \\times e \\times f = e \\times e \\times e$
$K$ 为矩阵中间数 $e$ 的立方。
当 $N > 3$ 时,放心大胆的用 dfs 搜一遍吧。
先把 $K$ 分解成 $a \\times b$ ,此题就变成了在 $N \\times N$ 这个矩阵中,填入 $a$ 与 $b$ 使每行每列以及两个对角线上有且只有一个 $a$ 和一个 $b$ ,其余位置填入 $1$ 。
先枚举 $a$ 与 $b$ 在两个对角线上如何放置,然后逐行枚举 $a$ 应该放哪一列,放完 $a$ 后逐行枚举放 $b$。发现 $N$ 从 $4$ 到 $1000$ 都是相当快的能跑出答案。
如果有大佬有直接构造的方法,欢迎在 QQ 群里提出。
这题复杂度 O(不知道)。
Problem M. Magical Water Cup
如果每杯水倒出的量都一样且第一杯水能倒出,则答案为无穷。
否则,先分别计算出每杯水最多可以倒多少次。
除了第一杯水,其他的水如果入得比出的多包括等于则可以倒无穷次,否则就是$\\left\\lfloor \\frac { A_{ i } }{ B_{ i }-B_{ i-1 } } \\right\\rfloor$次。
第一杯水是先出后入,先判断能否倒出第一次,如果可以就倒出,然后就和另外的水杯一样处理了;否则答案就是 0。
然后遍历一遍找到次数最小且离第一杯最近的那杯水,它就是最后不能操作的位置。简单计算即可得到答案
注意点:
- 第一杯水是先出后入要特判
- 数据超过int的范围
单组数据时间复杂度 $O(n)$。
---
最后,再次感谢您的参赛,祝您前程似锦、梦想成真。
以上是关于浙江财经大学第十四届程序设计竞赛题解的主要内容,如果未能解决你的问题,请参考以下文章
第十四届华中科技大学程序设计竞赛决赛同步赛 Beautiful Land
第十四届华中科技大学程序设计竞赛--JVarious Tree