codeforces极简题解
CF1713F
利用lucas定理,\(b_S\)表示下标\(T\)与\(S\)无交的\(a_T\)的异或,由于部分\(b_S\)未知,不能直接iFWT。回顾容斥:\([S=\emptyset]=\sum_{T\subseteq S}(-1)^|T|\),\([n=0]=\sum_{i=0}^{n}C(n,i)(-1)^i\),\([n=1]=\sum_{d|n}\mu(d)\),利用这种思想构造:令\(A=S\cap T\),\([A=\emptyset]=\sum_{B\subseteq A} 1 \mod 2\)。得到由\(a\)得到\(b\)做法:先求超集和,再求子集和。那么用iFWT先求子集和的逆,再求超集和的逆即可。
以下的\(\sum\)都表示异或求和\(b_S=\sum_{A\subseteq S}\sum_{A\subseteq T}a_T=\sum_{T}a_T(\sum_{A\subseteq S\cap T} 1 \mod 2)=\sum_{S\cap T=\emptyset}a_T\)
CF1707D
\(dp_{u,i}\)表示\(u\)子树中用了\(i\)次操作,\(u\)被删除要晚于\(u\)的第二晚的子树全部被删除,利用树上背包,合并子树时需要记录目前根被删除是第几次,可以做到\(O(n^3)\)。
更简单的办法是用二项式反演,也就是不要求每次操作至少删除一个节点,合并子树时可对应位置直接相乘,删除根的转移直接枚举根被删除是第几次即可,写出式子用前缀和即可\(O(n^2)\)。
CF1705F
加强版 https://www.luogu.com.cn/blog/1973224568qq/kao-shi-2021-coe-iii-d#
可以发现三次查询可以确定四个位置,次数是\(3/4n\),说明01具有特殊性(否则一定需要\(n\)次);然后CF1705F又给出了一个做法,先查询(1)FFF...和(2)TFTFTF...两种,每次用一次查询并对比(1)得到任意两个位置的信息,如果是TT和FF可以直接确定,否则带上一个新的位置再用一次查询并对比(2)得到三个位置的信息,次数是\(2/3n\),这个方法的思路就是通过\(x=0或2\)和\(y=0或1\)相加可以一次确定\(x\)和\(y\)的数值;那么扩展一下,设\(q\times n\)的矩阵\(A\)可以用\(q\)次询问解决规模为\(n\)的问题,那么构造\(2q\times (2n+q)\)的矩阵\(\begin{bmatrix}A& -A& 0\\ A& A& I\end{bmatrix}\),与大小为\(2n+q\)的向量\((v_1,v_2,v_3)^T\)相乘得到向量是\((Av_1-Av_2,Av_1+Av_2+v_3)^T\),即\((2Av_1+v_3,2Av_2+v_3)^T\),根据每一项的奇偶性即可得到\(v_3\)各项的值,再根据假设得到\(v_1\)和\(v_2\)的值。注意这样构造出的矩阵中的元素为\(\{-1,0,1\}\),直接写成两个矩阵的减,矩阵的行数乘二。最终\(n=\Theta(q\log q)\),次数是\(O(n/\log n)\)。
CF1698G
先把开头的0删去,让最终的答案增加0的个数。于是第一个为1的位一定是最开头,此后按照下标从小到大来异或,那么每次都是以串中第二个1为开头操作,直到只剩下两个1。而任何时候只有最后一次异或后的\(|S|-1\)个位需要考虑,因为这些位前面和后面一定全为0,那么这些位之多只有\(2^{|S|-1}\)种可能,答案不超过\(2^{|S|-1}|S|\),也就是直接模拟这个过程直到出现循环或得到答案,复杂度\(O(2^{|S|}|S|)\)。
设最终第二个1的位置为\(k\),那么检验的过程本质是在做一个异或下的\(2^k+1 \mod S\),直接倍增暴力除法即可\(O(|S|^2\log k)\)检验。根据之前所说答案不超过\(2^{|S|-1}\),用BSGS的思路结合“求逆”即可,总复杂度O(|S|22)。
利用多项式解释:若以第\(i\)个位置开头异或,则令操作多项式\(A\)包含项\(x^i\),那么就是异或下\(AS=2^k+1\),那么以\(S\)为模数得到\(2^k+1\equiv 0 \mod S\)。
CF1545C
如果某一列某个数只出现了一次,那么该行必选,并且由于保证存在一个另一行存在一个元素与该行相同,于是可以再排除一行;否则对于每一列每个数都出现两次,那么如果其中\(n\)行构成拉丁方,另外\(n\)行也构成拉丁方,对任意的\(i\),将第\(i\)行选入拉丁方的解与不将第\(i\)行选入拉丁方的解一一对应,可任取一行选入,排除一行,将答案乘二。此后行数减少2,每列需要考虑的数减少1,可以继续使用刚才的做法。