题目

  点这里看题目。

分析

  第一步可以将\(A\)数组转化成概率\(P(j)\):每一步操作异或\(j\)的概率。

  接着发现,\(x\)从\(0\)变成\(i\)的期望等于\(x\)从\(i\)变成\(0\)的期望。

  这样我们的起点虽然不一样,但是终点就是一样的。这样我们可以套用随机游走的模型:

  \(f(i)\):从\(i\)为起点变成\(0\)的期望。

  边界条件为\(f(0)=0\),剩下的转移为:

\[\begin{aligned}
&f(i)=1+\sum_{j=0}^{2^n-1}P(j)f(i\oplus j)\\
\Rightarrow&f(i)=1+\sum_{j\oplus k=i}P(j)f(k)\\
\Rightarrow&f(i)-1=\sum_{j\oplus k=i}P(j)f(k)
\end{aligned}
\]

  我们发现\(f\)是一个类似 " 自己卷自己 " 的转移。但是却又不太一样,因为多了 -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)-1)
\]

  发现我们不能确定卷起来的第 0 项是多少,因为我们的转移的边界是\(f(0)=0\)。

  但是我们设卷出来的第 0 项为\(x\),则可以得到:

\[\begin{aligned}
x+\sum_{i=1}^{2^n-1}(f(i)-1)
&=\sum_{i=0}^{2^n-1}\sum_{j\oplus k=i}P(j)f(k)\\
&=\sum_{i=0}^{2^n-1}f(i)\sum_{j=0}^{2^n-1}P(j)\\
&=\sum_{i=0}^{2^n-1}f(i)
\end{aligned}
\]

  也就是说,我们卷出来的东西应该和原来的\(f\)的和是一样的。

  然后可以得到\(x=f(0)+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(0)+2^n-1,f(1)-1,f(2)-1,...,f(2^n-1)-1)
\]

  我们发现\(f\)向量和结果向量比较像,并且有公共部分,就可以考虑碱法:

\[(f(0),f(1),f(2),...,f(2^n-1))\bigoplus(P(0)-1,P(1),P(2),...,P(2^n-1))=(2^n-1,-1,-1,...,-1)
\]

  这样我们就可以用 FWT 变换之后求出\(f\)向量来。

  但是我们发现 FWT 之后会出现第 0 项上都是 0 的情况,此时不能求逆元。

  不过,同时\(f(0)\)的变换后的值\(f'(0)\)也是毫无限制的。因此我们可以给\(f'(0)\)带入任意值,比如\(0\)。逆变换后第 0 项为\(k\)。\(f\)中每一项就都会多贡献\(k\),减掉就好。

代码

#include <cstdio>

const int mod = 998244353, inv2 = 499122177;
const int MAXN = 20, MAXL = ( 1 << 18 ) + 5; template<typename _T>
void read( _T &x )
{
x = 0;char s = getchar();int f = 1;
while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}
while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}
x *= f;
} template<typename _T>
void write( _T x )
{
if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }
if( 9 < x ){ write( x / 10 ); }
putchar( x % 10 + '0' );
} int F[MAXL], p[MAXL], h[MAXL];
int N, len; int qkpow( int base, int indx )
{
int ret = 1;
while( indx )
{
if( indx & 1 ) ret = 1ll * ret * base % mod;
base = 1ll * base * base % mod, indx >>= 1;
}
return ret;
} int inv( const int a ) { return qkpow( a, mod - 2 ); }
int fix( const int x ) { return ( x % mod + mod ) % mod; } void FWT( int *f, const int mode )
{
int t1, t2;
for( int s = 2 ; s <= len ; s <<= 1 )
for( int i = 0, t = s >> 1 ; i < len ; i += s )
for( int j = i ; j < i + t ; j ++ )
{
t1 = f[j], t2 = f[j + t];
if( mode > 0 ) f[j] = ( t1 + t2 ) % mod, f[j + t] = fix( t1 - t2 );
else f[j] = 1ll * ( t1 + t2 ) * inv2 % mod, f[j + t] = 1ll * fix( t1 - t2 ) * inv2 % mod;
}
} int main()
{
int s = 0;
read( N ); len = 1 << N;
for( int i = 0 ; i < len ; i ++ ) read( p[i] ), s = ( s + p[i] ) % mod;
s = inv( s );
for( int i = 0 ; i < len ; i ++ ) p[i] = 1ll * p[i] * s % mod;
for( int i = 1 ; i < len ; i ++ ) h[i] = mod - 1;
h[0] = len - 1, p[0] = fix( p[0] - 1 );
FWT( h, 1 ), FWT( p, 1 );
for( int i = 1 ; i < len ; i ++ ) F[i] = 1ll * h[i] * inv( p[i] ) % mod;
FWT( F, -1 );
int tmp = mod - F[0];
for( int i = 0 ; i < len ; i ++ ) write( ( tmp + F[i] ) % mod ), putchar( '\n' );
return 0;
}

[AGC034F]RNG and XOR的更多相关文章

  1. 【杂题】[AGC034F] RNG and XOR【集合幂级数】【FWT】【DP】

    Description 你有一个随机数生成器,它会以一定的概率生成[0,2^N-1]中的数,每一个数的概率是由序列A给定的,Pi=Ai/sum(Ai) 现在有一个初始为0的数X,每一轮随机生成一个数v ...

  2. @atcoder - AGC034F@ RNG and XOR

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个值域在 [0, 2^N) 的随机数生成器,给定参数 A[ ...

  3. AT4996-[AGC034F]RNG and XOR【FWT,生成函数】

    正题 题目链接:https://www.luogu.com.cn/problem/AT4996 题目大意 给出一个\(0\sim 2^n-1\)下标的数组\(p\),\(p_i\)表示有\(p_i\) ...

  4. [atAGC034F]RNG and XOR

    令$N=2^{n}$先将$\forall 0\le i<N,a_{i}$除以$\sum_{i=0}^{N-1}a_{i}$,即变为概率 令$f_{i}$表示$i$的答案(第一次变成$i$的期望步 ...

  5. Atcoder Grand Contest 034 F - RNG and XOR(FWT)

    Atcoder 题面传送门 & 洛谷题面传送门 tsc 考试前 A 的题了,结果到现在才写这篇题解--为了 2mol 我已经一周没碰键盘了,现在 2mol 结束算是可以短暂的春天 短暂地卷一会 ...

  6. GOOD BYE OI

    大米饼正式退役了,OI给我带来很多东西 我会的数学知识基本都在下面了 博客园的评论区问题如果我看到了应该是会尽力回答的... 这也是我作为一个OIer最后一次讲课的讲稿 20190731 多项式乘法 ...

  7. 【AtCoder】AGC034

    AGC034 刷了那么久AtCoder我发现自己还是只会ABCE(手动再见 A - Kenken Race 大意是一个横列,每个点可以跳一步或者跳两步,每个格子是空地或者石头,要求每一步不能走到石头或 ...

  8. [LeetCode] Maximum XOR of Two Numbers in an Array 数组中异或值最大的两个数字

    Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Find the maximum re ...

  9. 二分+DP+Trie HDOJ 5715 XOR 游戏

    题目链接 XOR 游戏 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

随机推荐

  1. 按图索骥,一些mysql知识点

    有事没事多看看 基础知识考察 基础知识,尤其是一些理论知识,例如: MySQL有哪些索引类型,这是个半开放式命题: 从数据结构角度可分为B+树索引.哈希索引.以及不常用的FULLTEXT索引(现在My ...

  2. easyui及读取xml

    本地测试地址例如http://localhost:6541/TreeExam/AuthorityTree TreeExam 是TreeExamController AuthorityTree是Tree ...

  3. Scaner对象

    目录 Scaner的基本概念 基本语法: 1.使用next() 的方式来接收字符串(使用频率较少) 2.使用nextLine()的方式来接收字符串 进阶使用(练习题) Scaner的基本概念 之前我们 ...

  4. 组件-vue自定义方法传递

    组件样式 面包屑导航栏 js Vue.component('bannerOne', { created() { console.log(this.bigbackColor); }, props: { ...

  5. web自动化之浏览器的窗口切换

    from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from seleni ...

  6. 0515项目优化和List集合

    0515项目优化和List集合 1. 项目优化 1.1 分析当前情况 问题 数据存储是数组形式,数据类型明确.复用度较低. 需求 Student操作使用的代码,StudentManager想要操作考虑 ...

  7. 添加nginx新模块,获取客户真实ip

    当前是客户端登录软件后台获取不到客户的真实ip而是云盾的代理ip 为了获取到真实ip后来发现通过配置nginx的read_ip模块就可以了 获取客户的真实ip使用Nginx的realip模块 当Ngi ...

  8. redis使用技巧十连胜,学会工作六到飞起

    Redis 在当前的技术社区里是非常热门的.从来自 Antirez 一个小小的个人项目到成为内存数据存储行业的标准,Redis已经走过了很长的一段路. 随之而来的一系列最佳实践,使得大多数人可以正确地 ...

  9. 【C++】常见易犯错误之数值类型取值溢出与截断(3)

    0.  前言 本节是“[C++]常见易犯错误之数值类型取值溢出与截断(1)” 的补充,主要探讨浮点型的取值溢出. 1. 相关知识 (1) 浮点型数据取值范围如下: 单精度型 float 3.4 * 1 ...

  10. [Unity2d系列教程] 002.引用外部DLL - C

    上一篇我们学习了Unity调用C#生成的外部DLL,但是有时候我们需要访问底层,不能不适用C生成的DLL.下面就让我们一起学习下,C如何生成. 1.创建一个C的控制台程序 2.点击确定->点击下 ...