2019.08.12【省选组】模拟

T1:这题的题意有点难懂。其实题目就是要我们先让所有工人把该学的都学了,然后使得无论工人们在那种选择的情况下都可以让所有机器都有人操作。

推一推不难发现:我们把整个二分图分成若干个连通块,所有机器都有人操作的充要条件就是每一个连通块都是一个完全二分图(即左边的每一个点向右边的每一个点都有连边)。

那么我们先把一开始的连通块都处理出来,设第i个连通块左边有x[i]个点,右边有y[i]个点,现在问题就转换成了要把这些连通块组合起来,使得每一个大的连通块左右点数相等,而最终答案=sum(s^2)最小。s表示每一个大连通块的左边的点数。这个很显然,因为sum(s^2)就是总的要连的的边数,用它减去一开始就有的边数就是答案。

那么现在问题就转换成了求最小的sum(s^2)。这个可以状压dp。设f[s][i]表示当前已选的连通块状态为s,最后一个还未选完的连通块集合目前x的和为i。那么我们枚举下一个要选的连通块(假设是k),于是我们便有两种转移方式:

1、f[s][i]->f[s+2^(k-1)][i+x[k]]

2、f[s][i]->f[s+2^(k-1)][0]

第1个很好理解,而第2个表示的是当前选完k之后我们就又完成了一个连通块集合。但是问题是我们怎样判断这个连通块集合是否合法(即sum(x)==sum(y))。这个其实很简单,我们只需要判断一下s+2^(k-1)这个集合中sum(x)是否等于sum(y)就可以了。可能有人会问这只是总的和,而不是当前连通块的和,但是我们注意到每一次完成一个连通块时都判断一次,所以总的一定是对的。

T2:首先我们注意到那条式子的计算只与(x[i]-x[j])、(y[i]-y[j])和(z[i]-z[j])有关,而x、y、z都在77以内,所以它们的差的范围只有155。我们设cnt[xx][yy][zz]表示差分别为xx、yy、zz的组合的出现次数,只要求出这个我们就可以求答案了。

那么现在我们来求cnt。这个可以用NTT做。对于一个x[i],我们将a数组中x[i]项和b数组中的77-x[i]项的系数都加1。那么对于一对x[i]和x[j],当a和b相乘时,a中的x[i]项与b中的77-x[j]项组合在一起就是x[i]-x[j]+77,那么这样我们就求出cnt了。

总结:当我们要求一个集合与另一个集合的元素两两组合出来的结果时,可以考虑FFT或NTT。

T3:题解待更新。

发布了149 篇原创文章 · 获赞 24 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/chiyankuan/article/details/99572170