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 o j)是否可以转移取决于所有队列中(i)是否在所有队列中(j)的后面。
由于数据随机,可以转移的对数为(n^2,cfrac{n^2}{2},cfrac{n^2}{4}...)
使用链表/队列维护可以转移的每一对即可。
这样子总计算时间复杂度降低到(nk(n+k))

原文地址:https://www.cnblogs.com/ctmlpfs/p/13929727.html