• [AGC034F] RNG and XOR


    一、题目

    点此看题

    二、解法

    \(f(i)\) 表示第一次走到 \(i\) 的期望操作次数,初始化 \(f(0)=0\),对于 \(i\in[1,2^n)\),转移:

    \[f(i)=1+\sum_{j=0}^{2^n-1} p(j)\cdot f(i\oplus j) \]

    由于转移有环,我们不妨写成集合幂级数的形式,对转移方程两边同时做异或卷积正变换:

    \[\vec f(i)=\vec g(i)+\vec p(i)\cdot \vec f(i)+\vec z(i) \]

    其中 \(g(i)=1\),代表转移方程中的常数项;\(z(0)\) 有值,\(\forall i>0,z(i)=0\),它用来强制 \(f(0)=0\)

    考虑 \(i=0\) 时,由于 \(\vec p(0)=1\),可以解出 \(\vec z(i)=-\vec g(0)\),即 \(z(0)=-\vec g(0)\)

    考虑 \(i>0\) 时,由于 \(\vec p(0)\not=0\),可以直接解出 \(\vec f(i)=0\)

    但是我们还不知道 \(\vec f(0)\) 是多少,由于 \(f(0)=\frac{1}{2^n}\sum_{i=0}^{2^n-1} \vec f(i)=0\),所以 \(\vec f(0)=-\sum_{i=1}^{2^n-1} \vec f(i)\),这样我们可以得到 \(\vec f\) 的每一项,把它逆变换就可以得到 \(f\),即我们的答案。

    总之这题是比较套路和明显的,时间复杂度 \(O(n2^n)\)

    #include <cstdio>
    const int M = (1<<18)+5;
    const int MOD = 998244353;
    const int inv2 = (MOD+1)/2;
    #define int long long
    int read()
    {
    	int x=0,f=1;char c;
    	while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
    	while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    	return x*f;
    }
    int n,m,p[M],x[M],y[M];
    int qkpow(int a,int b)
    {
    	int r=1;
    	while(b>0)
    	{
    		if(b&1) r=r*a%MOD;
    		a=a*a%MOD;
    		b>>=1;
    	}
    	return r;
    }
    void fwt(int *a,int n,int op)
    {
    	for(int i=1;i<n;i<<=1)
    		for(int j=0;j<n;j+=i<<1)
    			for(int k=0;k<i;k++)
    			{
    				int fe=a[j+k],fo=a[i+j+k];
    				a[j+k]=(fe+fo)%MOD;
    				a[i+j+k]=(fe-fo+MOD)%MOD;
    				if(op==-1)
    					a[j+k]=a[j+k]*inv2%MOD,
    					a[i+j+k]=a[i+j+k]*inv2%MOD;
    			}
    }
    signed main()
    {
    	n=1<<read();
    	for(int i=0;i<n;i++)
    		m+=p[i]=read(),y[i]=1;
    	m=qkpow(m,MOD-2)%MOD;
    	for(int i=0;i<n;i++)
    		p[i]=p[i]*m%MOD;
    	fwt(p,n,1);fwt(y,n,1);
    	int z=MOD-y[0];
    	for(int i=1;i<n;i++)
    	{
    		x[i]=(y[i]+z)*qkpow(MOD+1-p[i],MOD-2)%MOD;
    		x[0]=(x[0]+MOD-x[i])%MOD;
    	}
    	fwt(x,n,-1);
    	for(int i=0;i<n;i++)
    		printf("%lld\n",(x[i]+MOD)%MOD);
    }
    
  • 相关阅读:
    Android开发:fragment将事件传递回activity
    Android开发:使用DialogFragment实现dialog自定义布局
    菜鸟的开始
    SAP HANA中创建计算视图(Calculation View)
    SAP HANA studio 创建分析视图
    SAP HANA 创建属性视图
    SAP HANA 能做什么
    SAP HANA 是什么?
    SAP BW 例程(Routine)【开始例程、关键值或特性的例程、结束例程】
    DSO分类及应用
  • 原文地址:https://www.cnblogs.com/C202044zxy/p/16412412.html
Copyright © 2020-2023  润新知