• 「ZJOI2019」开关


    「ZJOI2019」开关

    神题


    前言

    \(\text{FWT}_{\oplus}(F(x))=F'(x)\)

    关于\(\text{FWT}_{\oplus}\)的展开式子,我发现大部分人都不晓得。。。。

    \([x^S]F'(x)=\sum_T(-1)^{|S\cap T|} [x^T]F(x)\)

    \(F(x)=\frac{F''(x)}{2^n}\)

    详细可以看这个

    定义\(\bigoplus\)为两个多项式的异或卷积

    \(\times\)为两个多项式对应项直接相乘

    \([x^S]F(x)\)表示\(F(x)\)的第\(S\)项的系数


    正文

    翻转过程是一个\(\oplus\)的过程,所以考虑用集合幂指数配合\(\text{FWT}_\oplus\)构造和求解方程

    事实上问题等价于从初始状态\(S\)跑到\(\empty\)的期望次数

    设从\(S\)\(\empty\)的期望次数生成函数为\(F(x)\),其中\([x^{\empty}]F(x)=0\)

    设转移函数\(G(x),[x^{\{i\}}]G(x)=p_i\)

    那么我们的方程就是\(F(x)\bigoplus G(x)+\sum x^S+cx^{\empty}=F(x)\)

    其中\(x^S\)表示这次转移之后答案要加一

    由于直接这样转移得到的方程显然是无穷解的,因为无法保证\([x^{\empty}]F(x)=0\)

    所以我们用一个常数项\(cx^{\empty}\)平衡这个问题,\(c\)现在是未知的

    \(\because F(x)\bigoplus G(x)+\sum x^S+cx^{\empty}=F(x)\)

    \(\therefore (F(x)\bigoplus G(x)+\sum x^S+cx^{\empty})'=F'(x)\)

    \(\therefore F'(x)\times G'(x)+(\sum x^S+cx^{\empty})'=F'(x)\)

    我们模拟一下\(G'(x)\)

    \([x^S]G'(x)=\sum_i(-1)^{|S\cap \{i\}|}[x^{\{i\}}]G(x)=\sum_{i\notin S}p_i-\sum_{i\in S}p_i\)

    再卷一下\((\sum x^S+cx^{\empty})'\)

    \((\sum x^S)'=\sum_S\sum_T(-1)^{|S\cap T|}x^S\)

    \(\because (-1)^{|S\cap T|} =\sum_{T\subset S}(-1)^|T|\cdot 2^{n-|S|}=[S=\empty]2^{n-|S|}\)

    \(\therefore (\sum x^S)'=2^n x^{\empty}\)

    \((cx^{\empty})'=\sum c\cdot x^S\)

    然后我们带入反解\([x^S]F'(x)\)


    \(S=\empty\)时,

    \([x^S]F'(x)\cdot [x^S]G'(x)+2^n+c=[x^S]F'(x)\)

    然后发现此时\([x^S]G'(x)=1\),那么就意味着\(2^n+c=0\)

    解出了\(c=-2^n\),但是此时我们实际上并不知道\([x^{\empty}]F'(x)\)的值


    \(S\ne \empty\)

    \([x^S]F'(x)\cdot [x^S]G'(x)+c=[x^S]F'(x)\)

    \([x^S]F'(x)(1-[x^S]G'(x))=c\)

    \[[x^S]F'(x)=-\frac{2^n}{1-\sum_{i\notin S}p_i+\sum_{i\in S}p_i}=-\frac{2^n}{2\sum_{i\in S}p_i} \]


    我们考虑要求出\([x^\empty]F'(x)\)的值

    \([x^{\empty}]F(x)=2^{-n}\cdot \sum [x^S] F'(x)=0\)

    \[[x^\empty]F'(x)-\sum_{S\ne \empty}\frac{2^n}{2\sum_{i\in S}p_i}=0 \]

    那么我们由\(F'(x)\)回代得到\([x^S]F(x)(S \ne \empty)\)


    \[[x^S]F(x)=2^{-n}\cdot \sum_T(-1)^{|S\cap T|}[x^T]F'(x) \]

    \[=2^{-n}([x^\empty]F'(x)+\sum_{T\ne \empty}(-1)^{|S\cap T|}[x^T]F'(x)) \]

    \[=\sum_{T\ne\empty}\frac{1}{2\sum_{i\in T}p_i}+2^{-n}\sum_{T\ne \empty}(-1)^{|S\cap T|}[x^T]F'(x) \]

    \[=\sum_{T\ne \empty,|S\cap T|\mod 2=1} \frac{1}{\sum_{i\in T} p_i} \]

    下面是一个背包,跑的同时统计一下就好了\(|S\cap T|\)的奇偶性就好了

    然后会发现事实上并没有必要特判\(S=\empty\)的情况

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cctype>
    #include<vector>
    using namespace std;
    
    #define reg register
    typedef long long ll;
    #define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i)
    #define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i)
    
    #define pb push_back
    template <class T> inline void cmin(T &a,T b){ ((a>b)&&(a=b)); }
    template <class T> inline void cmax(T &a,T b){ ((a<b)&&(a=b)); }
    
    char IO;
    int rd(){
    	int s=0;
    	int f=0;
    	while(!isdigit(IO=getchar())) if(IO=='-') f=1;
    	do s=(s<<1)+(s<<3)+(IO^'0');
    	while(isdigit(IO=getchar()));
    	return f?-s:s;
    }
    
    const int N=5e4,P=998244353;
    
    
    int n;
    int s[N],a[N],sum;
    int dp[110][N][2]; // 背包表示p之和为i,有j个不同的方案数
    ll Inv[N]; 
    ll c;
    
    ll qpow(ll x,ll k) {
    	ll res=1;
    	for(;k;k>>=1,x=x*x%P) if(k&1) res=res*x%P;
    	return res;
    } 
    
    
    
    int main(){
    	freopen("switch.in","r",stdin),freopen("switch.out","w",stdout);
    	n=rd();
    	rep(i,1,n) s[i]=rd();
    	dp[0][0][0]=1;
    	rep(i,1,n) {
    		int x=rd();
    		rep(j,0,sum) rep(k,0,1) rep(d,0,1) 
    			dp[i][j+d*x][k^(d&&s[i])]=(dp[i][j+d*x][k^(d && s[i])]+dp[i-1][j][k])%P;
    		sum+=x;
    	}
    	Inv[0]=Inv[1]=1;
    	rep(i,2,sum) Inv[i]=(P-P/i)*Inv[P%i]%P;
    	ll ans=0;
    	rep(i,1,sum) ans=(ans+Inv[i]*dp[n][i][1])%P; // 因为最后统计的时候没有空集,所以i从1开始
    	printf("%lld\n",ans*sum%P);
    }
    
    
    
    
    
    
  • 相关阅读:
    【LeetCode】链表 linked list(共34题)
    Construct Binary Tree from Preorder and Inorder Traversal<leetcode>
    Triangle <leetcode>
    Jump Game <leetcode>
    C++学习笔记 <const限定词>
    Search for a Range <leetcode>
    Subsets <leetcode>
    各种排序算法总结
    Unique Paths II <leetcode>
    C++学习笔记 <hash_map> <散列映射>
  • 原文地址:https://www.cnblogs.com/chasedeath/p/12969126.html
Copyright © 2020-2023  润新知