zoukankan      html  css  js  c++  java
  • 「ZJOI2019」开关 (概率期望+FWT)

    Address

    Luogu#5326

    LOJ#3045

    Solution

    首先把目标状态和初始状态互换,答案显然不变。

    考虑状压 \(\text{dp}\),现在记 \(F[S]\) 表示初始状态为 \(S\) 时,期望多少步到达目标状态。

    接下来假设 \(\sum_{i=1}^np_i=1\),如果输入不满足,把 \(p_i\) 全部除以 \(\sum p_i\) 即可。

    那么有:$$F[\emptyset]=0$$ $$S\ne\emptyset,F[S]=\sum_ip_i×(F[S\oplus \left{i\right}]+1)$$ 其中 \(\oplus\) 表示异或,\(\left\{i\right\}\) 表示只含 \(i\) 这一个元素的集合。

    \(G[\left\{i\right\}]=p_i\),当 \(|S|\ne 1\) 时,\(G[S]=0\)

    定义两个数组的异或卷积:如果 \(C=A\times B\),那么有:$$\forall S,C[S]=\sum_U\sum_V[U\oplus
    V=S]A[U]×B[V]$$

    定义两个数组的点积:如果 \(C=A\cdot B\),那么有 $$\forall S,C[S]=A[S]\times B[S]$$

    定义两个数组相加:如果 \(C=A+B\),那么有 $$\forall S,C[S]=A[S]+B[S]$$

    记一个全 \(1\) 数组 \(H\),即 \(\forall S,H[S]=1\)

    定义数组 \(R\),其中 \(R[\emptyset]=c\)\(\forall S\ne\emptyset,R[S]=0\)\(c\) 的值暂时还不知道,先用字母表示。

    那么可以得到:$$F=H+F×G+R$$ \(R\) 的存在是由于 \(S=\emptyset\)\(S\ne \emptyset\) 时,\(F[S]\) 的递推式不一样。

    定义变换 \(\tilde C\)(这玩意就是 \(FWT\) 变换,已经会的自觉跳过),其中 $$\tilde
    C[S]=\sum_T(-1)^{|S\cap T|}C[T]$$

    根据上式显然有:如果 \(C=A+B\),那么 \(\tilde C=\tilde A+\tilde B\)

    而且可以得到 $$C[S]=\frac{1}{2n}\sum_T(-1){|S\cap T|}\tilde C[T]$$

    其中 \(n\)\(S\) 的二进制位数,考虑证明上式。

    相当于证明:$$C[S]=\frac{1}{2n}\sum_A\sum_B(-1){|S\cap A|}(-1)^{|A\cap
    B|}C[B]$$

    \(S=B\) 时,上式化为 $$C[S]=\frac{1}{2n}\sum_A(-1){2|S\cap A|}C[B]$$

    即 $$C[S]=\frac{1}{2^n}\sum_AC[B]$$

    显然成立。

    \(S\ne B\) 时,我们随便抓一个只在 \(S,B\) 其中一者中出现的元素 \(i\)。对于某个集合 \(A'\),如果 \(i\notin A'\),那么 \(A=A'\)\(A=A'+\left\{i\right\}\) 的贡献互为相反数,因为:$$(-1)^{|S\cap
    A'|}(-1)^{|A'\cap B|}=-(-1)^{|S\cap
    (A'+\left{i\right})|}(-1)^{|(A'+\left{i\right})\cap B|}$$

    而这样的 \(A'\) 正好有 \(2^{n-1}\) 个,也就是说所有的 \(A\) 可以两两配对,贡献全部抵消,那么 \(S\ne B\)
    的时候就有:$$\frac{1}{2n}\sum_A(-1){|S\cap A|}(-1)^{|A\cap B|}=0$$

    证毕。

    有个性质:若 \(C=A\times B\),那么 \(\tilde C=\tilde A\cdot \tilde B\),证明如下:

    \[C[S]=\sum_L\sum_R[L\oplus R\oplus S=0]A[L]B[R] \]

    因为 \(\sum_T(-1)^{|S\cap T|}=2^n[S=\emptyset]\),所以:

    \[C[S]=\frac{1}{2^n}\sum_L\sum_R\sum_T(-1)^{|T\cap(L\oplus R\oplus S)|}A[L]B[R]\]

    接着,显然有 $$T\cap(L\oplus R\oplus S)=(T\cap L)\oplus(T\cap R)\oplus(T\cap
    S)$$

    那么 $$(-1)^{|T\cap(L\oplus R\oplus S)|}=(-1)^{|T\cap L|+|T\cap
    R|+|T\cap S|}$$

    上式可以理解为:若 \(z=x\oplus y\),那么 \(|z|\&1=(|x|+|y|)\&1\),因为异或相当于二进制下的不进位加法,所以
    \(x\oplus y\) 时,\(x,y\) 二进制中的 \(1\) 只会两两一起消掉,\(1\) 的总数的奇偶性不会变。

    所以

    \[C[S]=\frac{1}{2^n}\sum_L\sum_R\sum_T(-1)^{|T\cap L|}(-1)^{|T\cap R|}(-1)^{|T\cap S|}A[L]B[R]\]

    \[C[S]=(\frac{1}{2^n}\sum_T(-1)^{|T\cap S|})(\sum_L(-1)^{|T\cap L|}A[L])(\sum_R(-1)^{|T\cap R|}B[R])\]

    \[C[S]=(\frac{1}{2^n}\sum_T(-1)^{|T\cap S|})\tilde A[T]\times\tilde B[T]\]

    根据 $$C[S]=\frac{1}{2n}\sum_T(-1){|S\cap T|}\tilde C[T]$$

    可得 $$\tilde C[T]=\tilde A[T]\times\tilde B[T]$$

    证毕。

    让我们回到:$$F=H+F×G+R$$

    移项,得到 $$F(1-G)=H+R$$

    \(A=F(1-G)\),则 $$\tilde A[U]=\tilde F[U]×(1-\tilde G[U])$$

    \(A=H+R\),则 $$\tilde A[U]=\sum_T(-1)^{|T\cap U|}+c$$

    于是 $$\tilde F[U]×(1-\tilde G[U])=\sum_T(-1)^{|T\cap U|}+c$$

    \(U=\emptyset\) 时,有:$$\tilde G[U]=\sum p_i=1$$

    代入上式可得 \(c=-2^n\)

    \(U\ne\emptyset\) 时,有:$$\tilde G[U]=\sum_{i}(-1)^{[i∈U]}p_i$$

    此时 \(\tilde G[U]<1\),代入上式可得:

    \[\tilde F[U]=\frac{c}{1-\tilde G[U]}=-\frac{2^n}{1-\tilde G[U]} \]

    根据式子 $$\sum_T(-1)^{|S\cap T|}=2^n[S=\emptyset]$$

    可得 $$\sum_T\tilde F[T]=2^nF[\emptyset]=0$$

    那么 $$\tilde F[\emptyset]=-\sum_{T\ne \emptyset}\tilde F[T]=\sum_{T\ne \emptyset}\frac{2^n}{1-\tilde G[T]}$$

    现在可以由 \(\tilde F\) 变回 \(F\) 了,即 $$F[S]=\frac{1}{2n}\sum_T(-1){|S\cap T|}\tilde F[T]$$

    根据上面 \(\tilde F\) 的表达式,可得 $$F[S]=\sum_{T}(1-(-1)^{|S\cap T|})\frac{1}{1-\tilde G[T]}$$

    根据 \(\tilde G\) 的表达式可得 $$1-\tilde G[T]=\sum_{i∈T}2×p_i$$

    那么 $$F[S]=\sum_{T}(|S\cap T|&1)\frac{1}{\sum_{i∈T}p_i}$$

    \(dp[i][j][k]\) 表示前 \(i\) 个数的子集,和 \(S\) 交集大小的奇偶性为 \(k\),子集的 \(p\) 之和为 \(j\),满足这些条件的子集个数。

    那么 $$ans=\sum_j\frac{dp[n][j][1]}{j}$$

    但是如果 \(p_i\) 全部除以 \(\sum_{i=1}^np_i\)\(p_i\) 就不是整数了,无法 \(dp\)。所以一开始不要把 \(p_i\) 除以 \(\sum p_i\),直接 \(dp\)。 最后再把答案乘上 \(\sum p_i\) 即可。

    时间复杂度 \(\mathcal O(n\sum p_i)\)

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define ll long long
    
    template <class t>
    inline void read(t & res)
    {
    	char ch;
    	while (ch = getchar(), !isdigit(ch));
    	res = ch ^ 48;
    	while (ch = getchar(), isdigit(ch))
    	res = res * 10 + (ch ^ 48);
    }
    
    const int e = 105, o = 5e4 + 5, mod = 998244353;
    
    int n, s[e], p[e], sum, inv[o], f[e][o][2], ans;
    
    inline void add(int &x, int y)
    {
    	(x += y) >= mod && (x -= mod);
    }
    
    int main()
    {
    	read(n);
    	int i, j;
    	for (i = 1; i <= n; i++) read(s[i]);
    	for (i = 1; i <= n; i++) read(p[i]), sum += p[i];
    	inv[1] = 1;
    	for (i = 2; i <= sum; i++) inv[i] = (ll)(mod - mod / i) * inv[mod % i] % mod;
    	f[0][0][0] = 1;
    	for (i = 1; i <= n; i++)
    	for (j = 0; j <= sum; j++)
    	{
    		f[i][j][0] = f[i - 1][j][0];
    		f[i][j][1] = f[i - 1][j][1];
    		if (j >= p[i])
    		{
    			add(f[i][j][0], f[i - 1][j - p[i]][s[i]]);
    			add(f[i][j][1], f[i - 1][j - p[i]][s[i] ^ 1]);
    		}
    	}
    	for (i = 1; i <= sum; i++) ans = (ans + (ll)inv[i] * f[n][i][1]) % mod;
    	ans = (ll)ans * sum % mod; 
    	cout << ans << endl;
    	return 0;
    }
    
  • 相关阅读:
    js splice 属性实现数组的删除,插入,替换
    js var多等式变量的定义
    SQL Server 收缩数据库
    sql2005 全文索引
    显示器分辨率推荐
    使用javascript打开链接的多种方法
    运算优先级
    jqGrid
    asp.net IE 页面刷新固定位置
    Left Join ,On Where
  • 原文地址:https://www.cnblogs.com/cyf32768/p/12235774.html
Copyright © 2011-2022 走看看