这套题是真的很好,除了题目都有思路之外,还卡掉很多细节。
然而卡细节是考过的很多考试中从未考过的。
比如 T1 卡掉不开 long long 的巨佬们, T2 卡掉像我这样的蒟蒻连用 7 个 memset 的人。
因为这套题没有评测系统,所以就不附代码了 因为我也不知道是不是对的,虽然本地用 lemon 测过,但是学生机都是老年机!
本文不久会附上测试所用的数据、 std、题解和题目(pdf 版)
多年准备一场空 系列套题
T1 分数转换
Input file:frac.in
Output file:frac.out
Time limit:1.5seconds
Memory limit:512megabytes
题目

考场思考(正解)
一道送分题…
至于怎么将无线小数转分数,可自行百度。 巨佬可自推,其实像我这样的蒟蒻都可以退出来
但是要注意,会爆 int ,然而又有巨佬要开 __int128 ,结果被编译器坑掉,悲惨 CE。
其实开 long long 就可以了,何必要管那么多呢?
但是要注意,数据给出类似 0.33333[3] 的情况,这样的情况下,必须把输入处理为 0.[3]。
当然,这可能是我自己码代码时不注意出现的 bug ,巨佬们能够完全避免就别管这句话吧…
多年准备一场空,不开 long long 见祖宗。
T2 Slow Path Finding Algorithm (SPFA)


考场思路
这道题考场上看,感觉是比较简单的。
定义状态 dp[i][j] :走到 i 点,字符 j 出现次数的最大值。
为了还原路径,再定义 pre[i][j] 为 dp[i][j] 是从哪个点转移过来的。
然后根据这个状态,跑一边 spfa 即可。
但是因为是多组输入,所以注意数组的清空,然后我使用了 memset…
正解
思路都对,但是 memset 有点问题。
然后我被卡掉了…
下次我用 for() 来清,再也不装 X 了…
多年准备一场空,全用 mem 见祖宗。
T3 切面包

考场思路
这道题因为在考试的时候调 T2 过久,所以题都没看。
正解
20pts 思路
这个思路并不是测试点 1 的分,而是测试点 2 的分。
为什么?仔细一想,998224352499122176=21,并且没有事件一,那么这个数据点就很简单了。
想必具体思路不必过多赘述了吧 ????。
40pts 思路
测试点 2 过了之后,再暴力搜出所有的情况,时间复杂度 O(n+m⋅2n)。
这样就可以拿 40pts 的高分了,在对于这道题不够擅长的情况下, 200pts+40pts=240pts 已经是这一套题的最高分了。
100pts 思路
本思路来源于 High School Affiliated to Southwest University 学校的 jiangly 巨佬
下见题解图片,黄色标记处为题解错误,标记处应为 +2i=1∑n−2pipi+12少了一个系数 2。

现在我来加以解释 巨佬可直接忽略
首先,我们引入一个变量 xi 。
当 xi=1 时,表示这段面包的 i 位破掉。
当 xi=0 时,表示这段面包的 i 位是完好的。
那么,当我们用 xi 来表示这段面包的 破损/完好 情况时,得到的是一个 01 串。
那么,在什么时候,我们所拥有的面包段数会增加呢?
为了方便考虑,我们只关注两段面包的情况,先假设前面的面包完好,对于一些有问题的情况,我们在之后进行排除即可。
情况一:两个连续的面包完好的情况

即当 00 出现的时候,这时面包段数不会增加。
情况二:两个连续的面包破损的情况

即当 11 出现的时候,这时面包段数不会增加。
情况三:两段面包前好后破的情况

即当 01 出现的时候,这时面包段数不会增加。
情况四:两段面包前破后好的情况

即当 10 出现的时候,这时面包段数会增加。
通过对上面情况的分析,当前面的面包完好的情况下,只有当 10 情况出现时,面包段数会增加。
用数学语言表述就是x=1+i=1∑n−1(xi+xi+1−xixi+1)仔细体会这个公式,其中,前面 +1 是特殊处理最前面 x0=1 的情况,其他的细节不多说,你会发现我们前面的定义:
当 xi=1 时,表示这段面包的 i 位破掉。
当 xi=0 时,表示这段面包的 i 位是完好的。
这个定义是多么的方便。
我们再换个分析方式,假设每个断掉的面包都可以分出左右两段,如图:

这个时候,每个断掉的面包都可以分出两段,那么就有x=1+i=2∑n−1xi但是,问题呼之而出,当两段连续的面包一起破损的时候,是不会产生新的面包,要减去这样的情况。
那么最后的公式就是x=1+i=2∑n−1xi−i=1∑n−1xixx+1但是,这道题要求的是 x2 ,那么怎么做呢?
还能怎么做?暴力展开 x2 啊…
前面已经得到:
x2=(1+i=2∑n−1xi−i=1∑n−1xixx+1)2将这个括号打开:
x2=1+2≤i<n∑2≤j<n∑xixj+1≤i<n∑1≤j<n∑xixi+1xjxj+1+22≤i<n∑xi−21≤i<n∑xixi+1−22≤i<n∑1≤j<n∑xixjxj+1但是,我们最后要求的其实是期望,所以要将所有的 xi 换成概率 pi。
这里有点太复杂了,我们用概率运算一项一项地展开这六项。
第一项
1=1这个应该没有问题…我们已经解决 61 了,加油 ????。
第二项
2≤i<n∑2≤j<n∑xixj=(2≤i<n∑pi)2−2≤i<n∑pi2+2≤i<n∑pi具体做一下解释,情况 A 与 B (A=B) 一起发生的概率为
P(AB)=P(A)×P(B)但是,当情况 A 与 B (A=B)一起发生的概率为P(AA)=P(A)这是特殊情况,所以我们先要减去 A=B 这样的特殊情况的错误计算方式,再加上它们的正确计算方式。
第三项
1≤i<n∑1≤j<n∑xixi+1xjxj+1这种情况有点复杂,我们分开讨论。
-当 i=j 时(i=1∑n−1pipi+1)2−i=1∑n−1pi2pi+12+i=1∑n−1pipi+1
- 当 i=j−1 时1≤i≤n−2∑pipi+1pi+2−i=1∑n−2pipi+12pi+2
- 当 i=j+1 时1≤i≤n−2∑pipi+1pi+2−i=1∑n−2pipi+12pi+2其实是和第二个情况是一样的。
所以,第三项总共就是(i=1∑n−1pipi+1)2−i=1∑n−1pi2pi+12+i=1∑n−1pipi+1+21≤i≤n−2∑pipi+1pi+2−2i=1∑n−2pipi+12pi+2我们终于完成 21 了,然而我的脑细胞也被杀掉 21 了 ????。
第四项
可以直接建立等式22≤i<n∑xi=22≤i<n∑pi
第五项
也可以直接建立等式−2i=1∑n−1xixi+1=−2i=1∑n−1pipi+1
第六项
我们先将 - 抛弃,等会在括号之前加上即可。
先进行直接转换:2(i=2∑n−1pi)(i=1∑n−1pipi+1)
- 当 i=j 时,需要−2i=2∑n−1pi2pi+1+2i=2∑n−1pipi+1
- 当 i=j+1 时,需要−2i=1∑n−2pipi+12+2i=1∑n−2pipi+1
然后,我们将他们加起来,就是第六项了:
2(i=2∑n−1pi)(i=1∑n−1pipi+1)−2i=2∑n−1pi2pi+1+2i=2∑n−1pipi+1−2i=1∑n−2pipi+12+2i=1∑n−2pipi+1
不要忘记了前面我们省掉的 -
最后,将所有的化简结果 其实并没有化简,只有结果 加起来,就是我们的 x2 的了。
x2=1+(2≤i<n∑pi)2+3i=2∑n−1pi−5i=1∑n−1pipi+1+2p1p2+2pn−1pn−i=2∑n−1pi2+(i=1∑n−1pipi+1)2
−i=1∑n−1pi2pi+12+2i=1∑n−2pipi+1pi+2−2i=1∑n−2pipi+12pi+2−2(i=2∑n−1pi)(i=1∑n−1pipi+1)+2i=2∑n−1pi2pi+1+2i=1∑n−2pipi+12
公式终于推完了,可能有点乱,把一些项数进行了合并
然后,我们怎么做呢?
我的方法时使用八颗线段树分别维护 pi、pi2、pipi+1、pi2pi+1、pipi+12、pi2pi+12、pipi+1pi+2、pipi+12pi+2 即可。
多年准备一场空,不学数学见祖宗