西行寺无余涅槃
题意
给定 (n) 个稀疏多项式,求他们的 ( ext{xor}) 卷积。
具体的,每个多项式中有 (k) 个位置有数,值域为 ([0,2^m)) ,其中对于每个多项式的 (k) 个值从小到大排序后均为 (a_0,a_1,…,a_{k-1}) ,在第 (i) 个多项式中,(a_j) 所在位置为 (p_{i,j}) 。
(m+kleq 20,1leq nleq 10^6,kleq 10) 。
题解
暴力做法是对于每个多项式求完 (FWT) 后 (IFWT) 回去,显然这复杂度不可接受。
显然点值的不同个数为 (2^k) ,可以写成 (pm a_1pm a_2pm a_3pm…pm a_k) 。
不妨对于每个位置单独考虑在 (FWT) 的结果,设 (a_1+a_2+…+a_k) 出现了 (x_0) 次,(-a_1+a_2+…a_k) 出现了 (x_1) 次,(-a_0-a_1-…-a_k) 出现了 (x_{2^k-1}) 次。
如果我们一直 (x) 的具体取值就很容易知道该位置 (FWT) 后的值。
显然有
考虑一个元素 (alpha) 对答案的贡献,具体的设多项式 (F) ,对于 (iin[1,n]) ,在 (p_{i,alpha}) 的位置加一,对 (F) 做 (FWT) 的结果。
不妨令 (alpha=1) ,那么该多项式的当前考虑位置值为 (w) ,则。
因为 (x_0,x_2,…) 前面的系数为 (+1) ,而 (x_1,x_3,…) 前面的系数为 (-1) 。
同理可以得到 (k) 个方程,但这远低于 (2^k) 。
人类智慧一下如果 (alpha) 是个集合呢?
不妨设 (alpha={1,2}) ,那么对于 (iin [1,n]) ,在 (p_{i,1}igoplus p_{i,2}) 的位置加一,对 (F) 做 (FWT) 的结果在当前考虑位置值为 (w) 。
由于 (a igcap(b igoplus c)=(aigcap b)igoplus (a igcap c)) ,那么表达的为 (a_1,a_2) 前面系数相同的做 (+1) ,不同为 (-1) 。
推广一下就可以得到 (2^k) 个方程,但如何快速解呢?
事实上方程的系数是 (F={x_0,x_1,x_2,…,x_{2^k-1}}) ,(FWT) 后的结果,这也很好解释。
那么只要得到该 (2^k) 方程系数后做 (IFWT) 就可以得到 (x_0,x_1,x_2,…,x_{2^k-1}) 的具体值。
时间复杂度 (mathcal O(2^k(n+2^mcdot m))) 。
http://121.17.168.211:30000/contest/submission/9365
2021 山东省集 易见
题意
给定长度为 (n) 的字符串 (S) ,(Q) 组询问,每次询问一段区间内本质不同的子序列个数。
(1leq n,qleq 10^6) 。
题解
弱化版题目:「2017 山东一轮集训 Day6」子序列
本质不同子序列个数的求法可以通过建子序列自动机(模拟贪心)数 (DAG) 路径条数解决,或者矩阵乘法。
对于矩阵乘法,设 (f_{i,j}) 表示开头为 (i) ,预支下一个接上来的字符为 (j) 的方案数。
显然对于字符 (c) 来讲, (f_{0,0}=f_{1,1}=f_{2,2}=…=1,f_{c,0}=f_{c,1}=f_{c,2}=…=f_{c,26}=1) 设该矩阵为 (G(c)) 。
那么对于询问区间为 ([l,r]) 来说,(F=prod_{i=l}^r G(S_i)) 。 则最终答案为 (sum_{i=0}^{25} F_{i,26}) 。
故我们需要快速求一段区间内矩阵乘,可以维护前缀乘与前缀矩阵逆的乘。注意 ((AB)^{-1}=B^{-1}A^{-1}) 。
具体的,设 (P_i=prod_{j=1}^i G(j),Q_i=prod_{j=i}^1 G^{-1}(j)) ,那么答案写成 (Q_{l-1} imes P_r) 。
时间复杂度 (mathcal O((n+q)|z|^3)) ,仅能解决弱化版问题。https://loj.ac/s/1135303
观察一下 (G^{-1}(c)) 的性质,该矩阵可以写成
假设 (|z|=4,c=2) 。
若矩阵 (G^{-1}(c) imes F) ,事实上是除第 (c) 行其余行值不改变,而第 (c) 行每个值减去该列其他值。
观察一下 (G(c)) 的性质,该矩阵可以写成
若矩阵 (F imes G(c)) ,事实上是将除第 (c) 列其余值加上所在行的第 (c) 列值,第 (c) 列不变。
我们需要知道 (Q_i imes P_j) 最后一列的和,由于 (P_j=prod_{i=1}^j G(S_i)) ,我们可以将 (P_j) 看成一个变换,将列看成整体,维护在 (P_j) 时是通过每列的多少系数构成的。
这很好通过 (mathcal O(n|z|)) 的时间维护。
那么我们需要知道 (Q_i) 的每列和,这也十分好维护,时间复杂度 (mathcal O(n|z|)) .
故总时间复杂度 (mathcal O((n+q)|z|)) 。
PKUWC2018 Minimax
题解
显然有 (mathcal O(n^2)) 树形 (dp) 的做法,对其做线段树合并维护乘法以及区间和可以做到 (mathcal O(nlog n)) 。
PKUWC2018 随机算法
题解
显然有 (mathcal O(3^n)) 的状压 (dp) ,但这样记录了每个点是否选择与是否在独立集中,很难得到优化。
考虑对于不在独立集中的点,它出现的位置只要比相邻第一个出现在独立集时间靠后即为合法。
那么我们仅考虑在独立集的元素为 (S) ,设 (f_S) 表示独立集为 (S) ,并且考虑完 (Nex(S)) 的方案数。其中 (Nex(S)) 为 (S) 与 (S) 的邻居集合。
考虑在 (f(S)) 后面加入元素 (u) ,显然需要满足 (S) 不存在到 (u) 的边,但转移到 (f(S+u)) 的系数是什么呢 。
设需要考虑点的个数为 (x) ,后面还有 (y) 个点没有确定位置,那么通过插板法可以得到 (inom{x+y}{y-1}) 。
时间复杂度 (mathcal O(2^n imes n)) 。
PKUWC2018 猎人杀
题解
啥都不会/qaq。
一个很精妙的转化是每次 (dfrac{w_i}{sum w}) 的概率选择 (i) ,但若已经选择则再重新选择,使得最后均被选择,概率是相同的。
对答案容斥,记 (f(S)) 表示在 (1) 号点选择前至少 (S) 未被选择,则
由于 (sum wleq 10^5) ,考虑枚举 (sum_{uin S} w_u) ,那么需要知道 (sum (-1)^{|S|}) 。
答案可以写成 ([x^i]prod_{i=2}^n (1-x^{w_i})) ,分治 (NTT) 即可。时间复杂度 (mathcal O(sum wlog^2 sum w)) 。
PKUWC2018 随机游走
题解
对答案 (Min-Max) 容斥,那么需要对每个子集 (T) 求出从 (x) 走到 (T) 中点停止的期望时间。
普通消元是 (mathcal O(n^3)) 无法解决问题,不妨将转移写出,设 (f_u) 表示从 (u) 开始走到 (T) 中任意一点停止的期望时间,则
树上高斯消元很经典的套路是每个点 (f_u) 可以写成
其中,(A_u,B_u) 为常数。
证明也较为 ( ext{trival}) ,若 (u) 为叶子那么 (f_u=frac{1}{d_u}f_{fa_u}+1) ,(A_u=frac{1}{d_u},B_u=1) 。否则
即 (A_u=dfrac{1}{d_u-sum A_v},B_u=dfrac{sum B_v+d_u}{d_u-sum A_v}) 。
由于不能 (mathcal O(q2^n)) ,需要 (FWT) 处理出答案,(O(1)) 回答。
时间复杂度 (mathcal O(2^nn+q)) 。
PKUSC2018 最大前缀和
题解
对于 (a) 中仅存在一个负数的情况考虑枚举集合 (S) 使得 (S) 为最大前缀和,那么 (S) 的补集 (T) 需要满足 (T) 中前缀和均小于 (0) 。
这也是该题的解题思路。
令 (f_S) 表示 (S) 中的元素任意排列后最大前缀和为它本身的方案数,(g_S) 表示 (S) 中的元素任意排列后前缀和 (<0) 的方案数。
(g_S) 很好转移,每次往后新添一个元素看一下前缀和是否 (<0) ,时间复杂度 (mathcal O(2^nn)) 。
对于 (f_S) 来说往后新添一个字符很难进行转移,但往前填就会方便转移。
具体的,设当前序列 ({a_1,a_2,…,a_k}) ,由于 (sum_{i=1}^k a_i) 为最大值那么 对于 ([2,k]) 来说前缀最大值也应该为他本身,否则一定不优,并且 (sum_{i=2}^k a_igeq 0) ,否则仅选 (a_1) 即可。
那么我们只需要枚举第一个元素 (u) ,若 (Sum(S)geq 0) ,则 (f_{S+u}leftarrow f_{S}) 。
时间复杂度 (mathcal O(2^nn)) 。