jzoj6809题解

题目的限制等于从\(p\)个队列,每个队列里有\(n\)个数。
每次可以取出一个非空的队列的头部,询问方案数。
如果\(p\)较小,设\((s_1,s_2...s_p)\)表示第\(i\)个队列取到\(s_i\)的方案数。
题目要求不能取连续相同的\(p\)个数。这等于在空间上有一些点不能走。
把这个问题放在\(p\)维空间上。
这是个经典的问题。
在每个队列后加上一个\(n+1\)
考虑容斥,设\(f_i\)表示\(i\)点开始,前面的方案都没有出现连续的\(p\)个相同数,从当前点第一次开始出现连续相同的\(i....i\)的方案数。
先设\(f_i\)为当前点到\(n+1....n+1\)的方案。
然而我们前面计算了可能不是第一次到达当前点的方案,要减去。
使用组合数计算当前点到后继的方案数即可。
最后答案除以\(p!\)
这样子一次计算复杂度是\(n^2k\),太慢了。
但是我们在枚举端点,右端点增加时,组合数可以顺便维护。
这样子总计算时间复杂度降低到\(n^2k^2\)
注意到我们每个点的\(i\to j\)是否可以转移取决于所有队列中\(i\)是否在所有队列中\(j\)的后面。
由于数据随机,可以转移的对数为\(n^2,\cfrac{n^2}{2},\cfrac{n^2}{4}...\)
使用链表/队列维护可以转移的每一对即可。
这样子总计算时间复杂度降低到\(nk(n+k)\)

posted @ 2020-11-05 07:45  celerity1  阅读(57)  评论(0编辑  收藏  举报