奥林匹克五子棋
from qmqmqm
算法一
答案只与最后的棋盘有关。暴力枚举所有的棋盘然后判断是不是符合条件。
最终复杂度是
算法二
如果对于一组
明显如果
当
最终复杂度是
算法三
当
最终复杂度是
算法四
当
具体来说考虑
所以我们来考虑
可以想到,
这样一来,构造必须是一些
最终复杂度是
奥林匹克环城马拉松
from ftiasch,题解 from C_SUNSHINE
算法一
首先我们判断掉无解的情况,即存在一个点度数为奇数,此时方案数为
从
算法二
注意到树的每一条边数目都是偶数,且走过去和走回来的次数各占一半,令一个点的度数
首先先要确定每一条边的方向,这个其实就是在每一组重边中选一半向下,另一半向上,所以是
那么确定方向之后,欧拉回路如何计数呢?
我们有一个简单粗暴的方法,在每个点上对于每一条入边为它指定一个后继出边,这样边与边之间就连起来了,由于
妈呀我怎么过不了样例啊……
可以发现这样确定出来的不是欧拉回路,而是若干个环并在一起。
继续思考,我们可以使用一些类似“骨架”的东西来连接整个欧拉回路。而在连通图中,树是一个不错的选择。
我们令欧拉回路从
怎么统计这棵树呢?只要从向上走的边上拉一条出来就好了,方案数是
确定了最后一条出边之后找欧拉回路的过程其实也不难,对于一个点
于是方案数变成了
注意题目要求循环同构算同一种方案,但是你强制起点是
解决办法也很简单,
时间复杂度
算法三
观察树上的结论,我们会发现有向图的欧拉回路计数问题是有一个通用公式的:
其中
于是问题就变成了给图定向。
考虑一个环的情况,由于
接下来就是求环的树形图数目了。
对于
时间复杂度
算法四
环的问题解决之后,环套树问题就变得十分容易了。事实上,枚举任意一条环边正着走了多少次,根据有向图欧拉序列条件式
第二步就是树形图计数,这一步只要把环上的树形图计数和每个点的外向树树形图计数直接乘起来即可。
最后乘以
时间复杂度
奥林匹克数据结构
算法一
直接按照题意模拟,时间复杂度
算法二
考虑KMP的过程,我们同样考虑对b串建出KMP中的fail数组。那么我们发现,只需要将KMP中判断两个数相等的操作改成判断只要最后一个数字在整个序列中的名次相同即可。
用主席树实现可能会有常数问题。我们发现,我们只需要用树状数组预处理出b串中每个位置在它前面的所有数中的名次。然后再用树状数组维护当前的border,由于在KMP中border是单调的,所以每次border变化的时候暴力修改即可。
时间复杂度
算法三
考虑多串匹配,显然就是将KMP改成AC自动机,转移就是考虑下一个数在当前点到根的路径上的所有数中的名次,现在由于没有类似KMP的border的单调性,我们必须用主席树维护了。注意实现的时候,每次失配时一定要顺着fail链走上去而不是直接将转移置为fail节点的对应转移,否则会由于字符集太大无法保证复杂度(注意如果是一棵普通的trie而且字符集很小,一定要将转移置为fail节点的对应转移,因为普通trie的叶子节点深度之和可能很大)。
接着将原串在AC自动机上走一遍,最后更新子树和。注意如果暴力更新子树和会由于复杂度不对而超时。
注意要用平衡树或者hash存储转移。
时间复杂度
算法四
注意到如果
用树状数组加上异或哈希实现常数较小,可以通过四个
时间复杂度
算法五
我们考虑在线怎么做。对于普通的字符串,这个问题显然是用后缀三兄弟或后缀平衡树解决。那么在这个问题上是不是也可以如此呢?
后缀数组!
慢着……这玩意儿。。。后缀数组要求把后缀进行排序,很好,两个名次数组怎么比较顺序?
后缀自动机!
慢着……这玩意儿。。。一个结点能识别的子串的长度都不固定,怎么玩?
后缀平衡树!
慢着……这玩意儿。。。还是不知怎么比较两个名次数组的顺序啊。
后缀树!
慢着……这玩意儿。。。诶不慢,好像可以。
考虑用Ukkonen算法构造后缀树的过程,显然每一步也很容易用主席树推广到这题上。
然而直接用 Ukkonen 算法会被卡复杂度。我们把孩子数不等于
解决方法很简单,在找后缀链接的时候,如果它的父亲不是特殊节点,那就找它父亲的父亲,直到找到一个特殊节点,再从那个特殊节点开始求出当前点的后缀链接,可以证明这样的复杂度是正确的。
构造完后缀树之后求一遍子树和,每次在后缀树上跑一边查询即可。
时间复杂度
有人说,有后缀数组和后缀自动机了,还要后缀树干嘛?从这题可以看出,每个数据结构都有自己的特性。后缀树在这题上能够成功的原因,也许是因为他其实是某种后缀 Trie 的 AC 自动机吧。而 AC 自动机能够解决离线问题的原因,也许是因为他其实是推广后的 KMP 吧。这一切,也许正是奥林匹克数据结构的魅力所在。