Heteroaryl [Title] [AGC034F] RNG and XOR set of power series [] [] [DP] FWT

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/hzj1054689699/article/details/91635838

Description

You have a random number generator, it generates a certain probability [^ N-1 0,2] numbers, the probability of each number is given by the sequence A, Pi = Ai / sum (Ai)

There are a number of initial X 0, each one generates a random number v, the X becomes X xor v
request X into a desired number of rounds 0 ~ 2 ^ N-1 of the
answer to the modulo 998 244 353

N<=18,Ai<=1000

Solution

Wish to do the reverse, F [i] to i 0 of the desired number of rounds, apparently equivalent
readily available i> 0,
f [ i ] = 1 + f [ i   x o r   j ] p [ j ] f[i]=1+\sum f[i\ xor\ j]p[j]
. 1 to the left to
f [ i ] 1 = f [ i   x o r   j ] p [ j ] f[i]-1=\sum f[i\ xor\ j]p[j]
written in the form of a power series is set
( f [ 0 ] , f [ 1 ] , f [ 2 ] , . . . , f [ 2 N 1 ] ) ( p [ 0 ] , p [ 1 ] , p [ 2 ] , . . . , p [ 2 N 1 ] ) = ( ? , f [ 1 ] 1 , f [ 2 ] 1 , . . . , f [ 2 N 1 ] ) (f[0],f[1],f[2],...,f[2^N-1])\bigoplus(p[0],p[1],p[2],...,p[2^N-1])=(?,f[1]-1,f[2]-1,...,f[2^N-1])

? Because f [0] does not satisfy the transfer type

But we found p = 1 \sum p=1 , that is to say after the convolution sum unchanged
and therefore ? = f [ 0 ] + 2 N 1 ? = f[0]+2^N-1

The p [0] -1, on all disappear behind f

We can do a reverse convolution.
Specifically, the right side of the equal sign FWT, FWT and then multiplied by the middle of the inverse of the results of each, and then IFWT back.

No.
We found that 2 ^ N-1 + rear intermediate set of power series FWT (- 1) + (- 1) + ... + (- 1) which is a 0 (only this one is easy to prove 0), the corresponding on the right is 0, we can not get this one value left.

But we ignore the information, f [0] = 0
may wish to assume that this one left is 0, IFWT later go back and look f [0] how much worse that this one small contribution to how much push back on the line .

The time complexity of O (2 ^ N * N)

Code

#include <bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fod(i,a,b) for(int i=a;i>=b;--i)
#define L 19
#define M 262144
const int mo=998244353;
typedef long long LL;
using namespace std;
int n,m;
int a[M+1],b[M+1];
LL ksm(LL k,LL n)
{
	LL s=1;
	for(;n;n>>=1,k=k*k%mo) if(n&1) s=s*k%mo;
	return s;
}
const LL ny2=499122177;
void FWT(int *a,bool pd)
{
	for(int h=1;h<m;h<<=1)
		for(int j=0;j<M;j+=h*2)
			fo(i,0,h-1)
			{
				int v=a[i+j+h];
				a[i+j+h]=(a[i+j]-v+mo)%mo,a[i+j]=(a[i+j]+v)%mo;
				if(pd) a[i+j]=(LL)a[i+j]*ny2%mo,a[i+j+h]=(LL)a[i+j+h]*ny2%mo;
			}
}
LL pr[M];
int main()
{
	cin>>n;
	m=1<<n;
	LL sum=0;
	fo(i,0,m-1) scanf("%lld",&pr[i]),sum=(sum+pr[i])%mo;
	sum=ksm(sum,mo-2);
	a[0]=m-1;
	fo(i,1,m-1) a[i]=mo-1;
	fo(i,0,m-1) b[i]=pr[i]*sum%mo;
	b[0]=(b[0]-1+mo)%mo;
	FWT(a,0),FWT(b,0);
	int wz=0;
	fo(i,0,m-1)
	{
		if(b[i]!=0) a[i]=(LL)a[i]*ksm(b[i],mo-2)%mo;
		else a[i]=0,wz=i;
	}
	FWT(a,1);
	LL wp=(LL)(mo-a[0])*m%mo;
	FWT(a,0);
	a[wz]=wp;
	FWT(a,1);
	fo(i,0,m-1) printf("%d\n",a[i]);
}

Guess you like

Origin blog.csdn.net/hzj1054689699/article/details/91635838