HAOI2018 简要题解
\(~\)
以前做过的 [HAOI2018]染色、[HAOI2018]苹果树 暂时不更
[HAOI2018]字串覆盖 已经弃疗了。
总体难度 medium 偏 easy,但是 Luogu4495 [HAOI2018]奇怪的背包 想不到是真的脑抽。
代码可以在 https://gitee.com/yinjinrun/code-public-2/tree/master/Luogu 找到。
Luogu4494 [HAOI2018]反色游戏
小 \(C\) 和小 \(G\) 经常在一起研究搏弈论问题,有一天他们想到了这样一个游戏。有一个 \(n\) 个点 \(m\) 条边的无向图,初始时每个节点有一个颜色,要么是黑色,要么是白色。
现在他们对于每条边做出一次抉择:要么将这条边连接的两个节点都反色,要么不作处理.他们想把所有节点都变为白色,他们想知道在 \(2^m\) 种决策中,有多少种方案能达成这个目标。
小 \(G\) 认为这个问题太水了,于是他还想知道,对于第 \(i\) 个点,在删去这个点及与它相连的边后,新的答案是多少,对 \(10^9+7\) 取模。\(n \le 10^5\)
70 pts :\(n \le 2000\)
图论
生成树
感觉挺简单的,不理解为什么在洛谷评了黑。
看到 xor,首先想到的是高斯消元求解方程组然后 bitset
优化,然后答案就是 \(2^{自由元个数}\),复杂度 \(\mathcal O(\frac{n^6}{\omega})\)(可能算错了,但是能有 \(50\) 分)。
但是这个解法真的没什么用处……
但是通过这个解法以及观察样例,我们可以得知答案就是 \(2^t\) 的形式,进一步地,我们可以想到这个题和线性基有点类似,我们可以先插入一堆边,然后如果有一条边可以被别的边表示出来,那么就可以将答案 \(\times 2\)。
上面只是一个比较抽象的想法,但是可以让我们联想到环、生成树,于是我们可以将解法具体化:
- 遍历整个图,扣出生成树,记非树边的个数为 \(tot\),并且存在合法解,那么答案就是 \(2^{tot}\)
- 考虑证明:
- 从叶子开始考虑,如果该点为黑,那么操作对应其父亲的边,不断进行,直到到根位置。
- 此时如果根还是黑的,那么真的无解了,因为:
- 我们考虑操作一条链,那么只有链头链尾的颜色改变了,于是加入非树边对于答案没有任何影响。
- 于是在生成树上求解,然后根据根的点的颜色可以判断是否有解。
然后就是 \(\mathcal O(n^2)\) 解法了。
考虑 \(\mathcal O(n)\) 做法:
- ban 掉 \(x\) 点后,我们可以遍历其儿子,然后可以找到返祖边是否到了以 \(1\) 为根的子树;
- 进而可以确定剩余的非树边数量和原来 \(x\) 所在生成树的根的颜色。
然后就可以求解了。
另外要注意初始的图不连通。
Luogu4495 [HAOI2018]奇怪的背包
小 C 非常擅长背包问题,他有一个奇怪的背包,这个背包有一个参数 \(P\) ,当他向这个背包内放入若干个物品后,背包的重量是物品总体积对 \(P\) 取模后的结果。
现在小 C 有 \(n\) 种体积不同的物品,第 \(i\) 种占用体积为 \(V_i\) ,每种物品都有无限个。他会进行 \(q\) 次询问,每次询问给出重量 \(w_i\) ,你需要回答有多少种放入物品的方案,能将一个初始为空的背包的重量变为 \(w_i\)。注意,两种方案被认为是不同的,当且仅当放入物品的种类不同,而与每种物品放入的个数无关.不难发现总的方案数为 \(2^n\)。
由于答案可能很大,你只需要输出答案对 \(10^9 + 7\) 取模的结果。
动态规划
数论
没有想到结论,有不敢猜结论直接自闭了,其实以前是见过的,但是不知道为什么想不起来。
结论: \(w\) 能被 \(v_1, v_2, \dots, v_k\) 表示出来当且仅当 \(\gcd(P,v_1, v_2, \dots, v_k) | w\)。
然后我们可以设 \(f(x)\) 表示 \(\gcd\) 为 \(x\) 的集合的个数,复杂度 \(\mathcal O(n d(P))\),其中 \(d(P) \le 1344\)。
然后可以将 \(\gcd(v, P)\) 的相同的元素合并,于是复杂度就是 \(O \mathcal (d(P)^2\log P)\) 了(还有 \(\gcd\) 复杂度)。