【日总结】2023.3.24
改题改的太慢了!!!
脑子有问题场。
2023省选武汉联测10(GDKOI2023 Day1)
T1 矩阵
大概是经典问题。
矩阵乘矩阵很慢,但是矩阵乘向量很快。我们两边左乘一个横向量 \(a\),检查是否有 \(aAB=aC\) 即可。
\(a\) 随便随机一个就行,反正值域很大,撞不上。
T2 错排
考场降智。
考虑把错排转换一下。排列可以看做是若干个置换环,那么错排就是满足置换环的大小均大于等于 \(2\)。
那么按照这个思路,考虑题目中给出的限制,实际上就是前 \(m\) 个点连的边都是往外连的。那么我们就有 \((n - m)^{\underline m}\) 种连的方案。那么对于这 \(m\) 个连边,我们有两种情况:
- \(u \to v \to u\),即直接连回去;
- \(u \to v \to \cdots \to u\)。
我们先枚举第一种情况有多少个,然后剩下的点我们可以把 \(u \to v\) 缩成一个点。那么方案数实际上就是把剩下的点错排的方案数。
设 \(d_n\) 为错排方案数,那么答案实际上就等于:
先不管前面的系数,我们可以把后面写成多项式的形式。设 \([x^n] F(x) = d_n\),那么答案其实就是:
这是一个很经典的问题了。我们考虑分块,预处理出 \(G_i(x)=(x+1)^{iB} F(x)\),然后每次查询时只需要计算 \([x^z]G_{x}(x+1)^y\)。由于 \(y < B\),那么我们可以只枚举后面的 \(O(B)\) 个系数,这样询问的复杂度为 \(O(nB)\),而预处理的复杂度为 \(O(\frac{n}{B} n \log n)\),取 \(B=\sqrt{n \log n}\),则有总复杂度 \(O(n \sqrt{n \log n})\)。
上面的式子还可以推出递推式,从而使用莫队 / 分块计算答案,但是需要观察的东西太多了,不如这个做法直接。
T3 异或图
嗯嗯嗯嗯嗯嗯嗯嗯嗯。
其实是两个经典问题拼在了一起。
首先考虑 \(m=0\) 时咋做。首先肯定是类似于数位 DP 的方式从高位往低位做,直接做是 \(O(2^n \log a)\) 的,显然无法接受。
可以发现一个性质:假如出现了某个数不卡上界之后,那么其它的数是可以任意选择的,因为无论选择任何数,都可以通过这个不卡上界的数使得最后的异或和等于 \(c\)。
那么我们就可以只 DP 当前这一层选多少 \(0, 1\),如果没有都卡上界就可以直接计算出方案数,于是复杂度降到了 \(O(n \log a)\)。
然后考虑边怎么处理。很自然的想到容斥,最暴力的做法就是枚举边,然后钦定相连的数相等,形成若干个连通块,每个连通块的 \(a\) 设为原来的最小值。发现假如连通块大小为偶数,那么它不会对异或和产生贡献,只会对方案数产生贡献,而奇数就可以当成一个点来计算。那么这样的复杂度就是 \(O(2^m n \log a)\) 的。
上述算法的缺点是什么?实际上很多种连边方案得到的连通块方案是完全相同的,枚举边集是很浪费的。我们考虑直接枚举最后连通块的方案,然后考虑有多少种边集能够形成当前这种连通块的方案。那么我们可以先对每个连通块计算出其所有合法边集的容斥系数的和,然后再卷积起来得到整体的容斥系数的和。然后我们再对每种连通块的方案计算答案即可。
卷积的时候需要记录当前集合中作为 \(a_i\) 最小值的点的集合,这样我们需要枚举一次子集一次超集,总复杂度为 \(O(4^n)\)。无用状态挺多的,所以跑的很快。