2016-E09-team2

从 Trac 迁移的文章

这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。

原文章内容如下:

||User||Problem||Result||Memory||Time||Language||Length||Submit Time||
||TaZoF||E||MLE|| || ||G++||1904||2016-10-04 16:53:36||
||TaZoF||E||MLE|| || ||G++||1883||2016-10-04 16:51:26||
||TaZoF||E||WA|| || ||G++||1884||2016-10-04 16:48:10||
||TaZoF||D||AC||1648||2308||G++||1876||2016-10-04 16:42:37||
||TaZoF||D||WA|| || ||G++||1807||2016-10-04 16:20:39||
||TaZoF||B||WA|| || ||G++||814||2016-10-04 15:36:35||
||TaZoF||E||MLE|| || ||G++||1798||2016-10-04 15:21:56||
||TaZoF||E||MLE|| || ||G++||1743||2016-10-04 15:20:05||
||TaZoF||E||MLE|| || ||G++||1705||2016-10-04 15:17:46||
||TaZoF||E||MLE|| || ||G++||1807||2016-10-04 15:11:01||
||TaZoF||E||RE|| || ||G++||1949||2016-10-04 15:04:54||
||TaZoF||E||MLE|| || ||G++||1765||2016-10-04 14:50:11||
||TaZoF||G||AC||9416||109||G++||1022||2016-10-04 14:49:07||
||TaZoF||E||MLE|| || ||G++||1665||2016-10-04 14:38:31||
||TaZoF||E||RE|| || ||G++||1665||2016-10-04 14:38:01||
||TaZoF||E||RE|| || ||G++||1646||2016-10-04 14:34:21||
||TaZoF||E||MLE|| || ||G++||1647||2016-10-04 14:33:35||
||TaZoF||G||WA|| || ||G++||1019||2016-10-04 14:15:34||
||TaZoF||A||AC||1888||374||G++||476||2016-10-04 13:36:41||
||TaZoF||A||WA|| || ||G++||571||2016-10-04 13:23:29||
||TaZoF||L||AC||5412||624||G++||1284||2016-10-04 13:00:04||
||TaZoF||K||AC||5564||171||G++||676||2016-10-04 12:42:47||
||TaZoF||C||AC||9240||1310||GCC||389||2016-10-04 12:29:13||

== 流水账 ==
开场我们很快过了三个简单题,'''C1y14''','''K1y27''','''L1y45'''。之后我与hzf学长讨论A题,starve学长写G。A题在忽略了一个问题错了一次之后'''A2y81'''。starve学长的G貌似碰到了一点问题,我替学长写G,不过一开始错了...starve学长发现E似乎是回文树裸题,我检查G的时候学长就在写E,然而不断MLE...G题我把记忆化部分去掉之后就通过了,不过不是很理解,准备结束后再思考思考,'''G2y154'''。

之后starve学长继续尝试节省E的空间但是并没有成功,hzf学长似乎想到了B和J的做法,可惜后来都发现了错误。最后starve学长放弃了E写了写D,'''D2y272'''。最后我们想了想E,觉得只要用Manacher就可以了,但是时间不太够了。

== 总结 ==
 * 做得不好的地方
   * 套用模板太盲目,而且模板比较偏。套用之间时空复杂度没有仔细分析。

== 题解 ==
C,G,K,L比较简单,略过...
=== A - ATM Machine ===
设f[i][j]表示还有i次警告,且已知ATM里最多还有j的钱的期望步数。由于ATM机里有多少钱是等概率的,所以如果我们这次取走了k的钱,就会有k/(j+1)的概率被警告,(j+1-k)/(j+1)的概率不被警告。所以容易得到转移方程f[i][j] = min(k/(j+1)*f[i-1][k-1] + (j+1-k)/(j+1)*f[i][j-k])。

这是一个三方的转移方程,但是我们知道,如果警告次数大于log次,只要使用二分的策略就可以了。所以我们只要预处理i = 0~15的情况即可,这样就是O(n^2^logn)的了。读入询问的时候把警告次数和15比较一下,如果高于15就当作15.

=== D - How Many Triangles ===
找锐角三角形不太容易,我们把问题变成找钝角和直角三角形。我们只要枚举钝角或直角的顶点,然后把其它点极角排序一下就能用线性的时间做了。应该还是比较经典的方法。

=== E - Interesting ===
设L[i]表示所有右端点在i处的回文串的左端点位置之和,R[i]表示所有左端点在i处的回文串的右端点位置之和。显然答案就是对所有L[i]*R[i+1]求和。

L[i]应该怎么算呢?如果我们能用sumL[i]表示所有右端点在i处的回文串的中心位置之和*2,sizL[i]表示所有右端点在i处的回文串的数量。很显然我们有L[i] = sumL[i]-sizL[i]*i,R[i]同理。因为我们要从左到右枚举i,所以只要用差分的方式算出sumL[i]和sizL[i]。

=== J - Prefix ===
感觉是出题人的恶意,空间给得那么少...?

如果我们能把所有字符串的前缀哈希一下,这个问题就变成了“求一段区间内有几种不同的值”。这个问题强制在线的话可以用可持久化线段树来完成。

不过哈希函数不是很靠谱...我们可以改用一棵Trie树来维护所有字符串的前缀。

== 补题 ==
=== TsReaper ===
~~E~~,H,~~J~~
UserProblemResultMemoryTimeLanguageLengthSubmit Time
TaZoFEMLE G++19042016-10-04 16:53:36
TaZoFEMLE G++18832016-10-04 16:51:26
TaZoFEWA G++18842016-10-04 16:48:10
TaZoFDAC16482308G++18762016-10-04 16:42:37
TaZoFDWA G++18072016-10-04 16:20:39
TaZoFBWA G++8142016-10-04 15:36:35
TaZoFEMLE G++17982016-10-04 15:21:56
TaZoFEMLE G++17432016-10-04 15:20:05
TaZoFEMLE G++17052016-10-04 15:17:46
TaZoFEMLE G++18072016-10-04 15:11:01
TaZoFERE G++19492016-10-04 15:04:54
TaZoFEMLE G++17652016-10-04 14:50:11
TaZoFGAC9416109G++10222016-10-04 14:49:07
TaZoFEMLE G++16652016-10-04 14:38:31
TaZoFERE G++16652016-10-04 14:38:01
TaZoFERE G++16462016-10-04 14:34:21
TaZoFEMLE G++16472016-10-04 14:33:35
TaZoFGWA G++10192016-10-04 14:15:34
TaZoFAAC1888374G++4762016-10-04 13:36:41
TaZoFAWA G++5712016-10-04 13:23:29
TaZoFLAC5412624G++12842016-10-04 13:00:04
TaZoFKAC5564171G++6762016-10-04 12:42:47
TaZoFCAC92401310GCC3892016-10-04 12:29:13

流水账

开场我们很快过了三个简单题,C1y14K1y27L1y45。之后我与hzf学长讨论A题,starve学长写G。A题在忽略了一个问题错了一次之后A2y81。starve学长的G貌似碰到了一点问题,我替学长写G,不过一开始错了...starve学长发现E似乎是回文树裸题,我检查G的时候学长就在写E,然而不断MLE...G题我把记忆化部分去掉之后就通过了,不过不是很理解,准备结束后再思考思考,G2y154

之后starve学长继续尝试节省E的空间但是并没有成功,hzf学长似乎想到了B和J的做法,可惜后来都发现了错误。最后starve学长放弃了E写了写D,D2y272。最后我们想了想E,觉得只要用Manacher就可以了,但是时间不太够了。

总结

  • 做得不好的地方
    • 套用模板太盲目,而且模板比较偏。套用之间时空复杂度没有仔细分析。

题解

C,G,K,L比较简单,略过...

A - ATM Machine

设f[i][j]表示还有i次警告,且已知ATM里最多还有j的钱的期望步数。由于ATM机里有多少钱是等概率的,所以如果我们这次取走了k的钱,就会有k/(j+1)的概率被警告,(j+1-k)/(j+1)的概率不被警告。所以容易得到转移方程f[i][j] = min(k/(j+1)*f[i-1][k-1] + (j+1-k)/(j+1)*f[i][j-k])。

这是一个三方的转移方程,但是我们知道,如果警告次数大于log次,只要使用二分的策略就可以了。所以我们只要预处理i = 0~15的情况即可,这样就是O(n2logn)的了。读入询问的时候把警告次数和15比较一下,如果高于15就当作15.

D - How Many Triangles

找锐角三角形不太容易,我们把问题变成找钝角和直角三角形。我们只要枚举钝角或直角的顶点,然后把其它点极角排序一下就能用线性的时间做了。应该还是比较经典的方法。

E - Interesting

设L[i]表示所有右端点在i处的回文串的左端点位置之和,R[i]表示所有左端点在i处的回文串的右端点位置之和。显然答案就是对所有L[i]*R[i+1]求和。

L[i]应该怎么算呢?如果我们能用sumL[i]表示所有右端点在i处的回文串的中心位置之和*2,sizL[i]表示所有右端点在i处的回文串的数量。很显然我们有L[i] = sumL[i]-sizL[i]*i,R[i]同理。因为我们要从左到右枚举i,所以只要用差分的方式算出sumL[i]和sizL[i]。

J - Prefix

感觉是出题人的恶意,空间给得那么少...?

如果我们能把所有字符串的前缀哈希一下,这个问题就变成了“求一段区间内有几种不同的值”。这个问题强制在线的话可以用可持久化线段树来完成。

不过哈希函数不是很靠谱...我们可以改用一棵Trie树来维护所有字符串的前缀。

补题

TsReaper

E,H,J

附加文件