Atcoder 题面传送门 & 洛谷题面传送门

tsc 考试前 A 的题了,结果到现在才写这篇题解……为了 2mol 我已经一周没碰键盘了,现在 2mol 结束算是可以短暂的春天 短暂地卷一会儿 OI 了((

u1s1 写这篇题解的时候我连题都快忘了。。。

首先设 \(b_i=\dfrac{A_i}{\sum\limits_{j=0}^{2^n-1}A_j}\),其次碰到这种期望类的题目我们考虑套路地设 \(p_i\) 表示异或得到 \(i\) 的概率,那么有 \(p_i=\sum\limits_{j=0}^{2^n-1}p_jb_{i\oplus j}+1\),\(p_0=0\)。这个状态定义是存在后效性的,而高斯消元 \(8^n\) 又显然会超时,因此考虑从这个转移式本身入手进行优化。注意到这个转移式长得有点像异或卷积,因此考虑用异或卷积的形式将这个式子写出来,即 \(p=p\times b+I\),其中 \(\forall i,I_i=1\),异常好理解。

不过事实上这个式子是有个 bug 的,\(p_0=0\),而将 \(p_0\) 带到右边去就不一定等于 \(0\) 了,也就是说左边实际上要加上一个常数 \(X\),即 \(p+X=p\times b+I(X\in\mathbb{R})\)(事实上很多生成函数的题也需要注意常数项的问题,比如说斐波那契数列,这里就不再赘述了)。怎么求这个 \(X\) 的值呢?这里又是一个套路,将左边每一项都变成它的系数和,相当于多项式里的令 \(x=1\),那么可以得到 \((\sum\limits_{i=0}^{2^n-1}p_i)+X=(\sum\limits_{i=0}^{2^n-1}p_i)\times (\sum\limits_{i=0}^{2^n-1}b_i)+(\sum\limits_{i=0}^{2^n-1}I_i)\),而显然 \(\sum\limits_{i=0}^{2^n-1}b_i=1\),故 \(X=\sum\limits_{i=0}^{2^n-1}I_i=2^n\),因此 \(p+2^n=p\times b+I\),简单移个项可得 \(2^n-I=p\times(b-1)\),故 \(p=\dfrac{2^n-I}{b-1}\),把上下两个幂级数 FWTxor 一下相除再 FWTxor 回去即可得到 \(p\)。

还有一个小问题,就是在求逆元的时候有可能会出现分母为 \(0\) 的情况。事实上,由于 \(A_i\le 1000\),因此从所有 \(b_i\) 中任意选出一些出来它们的分子分母都 \(<998244353\),记 \(F=\text{FWT}(b-1)\),那么必然有 \(F_i\le 0(i\ne 0)\),而 \(F_0=-1+\sum\limits_{i=0}^{2^n-1}b_i=0\),因此出错的只可能是 \(F_0\)。不过这个问题很好解决,我们已知 \(p_0=0\),而显然对于一个幂级数 \(F\) FWTxor 后得到的幂级数 \(G\),常数项上加上一个常数 \(C\) 对于 \(F\) 的作用效果就是每一项都加上 \(C\),因此我们只需输出 \(p_i-p_0\) 即可。

const int MAXP=1<<18;
const int MOD=998244353;
int qpow(int x,int e=MOD-2){
int ret=1;
for(;e;e>>=1,x=1ll*x*x%MOD) if(e&1) ret=1ll*ret*x%MOD;
return ret;
}
int n,a[MAXP+5],b[MAXP+5],c[MAXP+5];
void FWTxor(int *a,int len,int type){
for(int i=2;i<=len;i<<=1)
for(int j=0;j<len;j+=i)
for(int k=0;k<(i>>1);k++){
int X=a[j+k],Y=a[(i>>1)+j+k];
a[j+k]=1ll*(X+Y)*type%MOD;
a[(i>>1)+j+k]=1ll*(X-Y+MOD)*type%MOD;
}
}
int main(){
scanf("%d",&n);n=1<<n;int sum=0;
for(int i=0;i<n;i++) scanf("%d",&a[i]),sum+=a[i];sum=qpow(sum);
for(int i=0;i<n;i++) a[i]=1ll*a[i]*sum%MOD;a[0]=(a[0]-1+MOD)%MOD;
for(int i=0;i<n;i++) b[i]=MOD-1;b[0]=(b[0]+n)%MOD;
FWTxor(a,n,1);FWTxor(b,n,1);
for(int i=0;i<n;i++) c[i]=1ll*b[i]*qpow(a[i])%MOD;
FWTxor(c,n,MOD+1>>1);
for(int i=0;i<n;i++) printf("%d\n",(c[i]-c[0]+MOD)%MOD);
return 0;
}

Atcoder Grand Contest 034 F - RNG and XOR(FWT)的更多相关文章

  1. Atcoder Grand Contest 030 F - Permutation and Minimum(DP)

    洛谷题面传送门 & Atcoder 题面传送门 12 天以前做的题了,到现在才补/yun 做了一晚上+一早上终于 AC 了,写篇题解纪念一下 首先考虑如果全是 \(-1\)​ 怎么处理.由于我 ...

  2. Atcoder Grand Contest 003 F - Fraction of Fractal(矩阵乘法)

    Atcoder 题面传送门 & 洛谷题面传送门 Yet another AGC F,然鹅这次就没能自己想出来了-- 首先需注意到题目中有一个条件叫做"黑格子组成的连通块是四联通的&q ...

  3. Atcoder Grand Contest 016 F - Games on DAG(状压 dp)

    洛谷题面传送门 & Atcoder 题面传送门 如何看待 tzc 补他一个月前做的题目的题解 首先根据 SG 定理先手必输当且仅当 \(\text{SG}(1)=\text{SG}(2)\). ...

  4. Atcoder Grand Contest 010 C - Cleaning 树贪心(伪)

    C - Cleaning 题目连接: http://agc010.contest.atcoder.jp/tasks/agc010_c Description There is a tree with ...

  5. Atcoder Grand Contest 001 D - Arrays and Palindrome(构造)

    Atcoder 题面传送门 洛谷题面传送门 又是道思维题,又是道把我搞自闭的题. 首先考虑对于固定的 \(a_1,a_2,\dots,a_n;b_1,b_2,\dots,b_m\) 怎样判定是否合法, ...

  6. Atcoder Grand Contest 024 E - Sequence Growing Hard(dp+思维)

    题目传送门 典型的 Atcoder 风格的计数 dp. 题目可以转化为每次在序列中插入一个 \([1,k]\) 的数,共操作 \(n\) 次,满足后一个序列的字典序严格大于前一个序列,问有多少种操作序 ...

  7. Atcoder Grand Contest 008 E - Next or Nextnext(乱搞+找性质)

    Atcoder 题面传送门 & 洛谷题面传送门 震惊,我竟然能独立切掉 AGC E 难度的思维题! hb:nb tea 一道 感觉此题就是找性质,找性质,再找性质( 首先看到排列有关的问题,我 ...

  8. AtCoder Grand Contest 002 F:Leftmost Ball

    题目传送门:https://agc002.contest.atcoder.jp/tasks/agc002_f 题目翻译 你有\(n*k\)个球,这些球一共有\(n\)种颜色,每种颜色有\(k\)个,然 ...

  9. AtCoder Grand Contest 017 F - Zigzag

    题目传送门:https://agc017.contest.atcoder.jp/tasks/agc017_f 题目大意: 找出\(m\)个长度为\(n\)的二进制数,定义两个二进制数的大小关系如下:若 ...

随机推荐

  1. vue如何监听数组的变化

    export function def (obj: Object, key: string, val: any, enumerable?: boolean) { Object.defineProper ...

  2. 第0次 Beta Scrum Meeting

    本次会议为Beta阶段第0次Scrum Meeting会议 会议概要 会议时间:2021年5月27日 会议地点:「腾讯会议」线上进行 会议时长:1小时 会议内容简介:本次会议为Beta阶段启程会议,主 ...

  3. PCB中,Solder Mask与Paste Mask有啥区别呢?

    Solder Mask Layers: 即阻焊层.顾名思义,他的存在是为了防止PCB在过波峰焊的时候,不应涂锡的地方粘上锡. 可以简单理解为一个洞,该区域(洞)以外的地方,都不允许有焊锡,即只能涂绿油 ...

  4. Linux C语言多线程编程实例解析

    Linux系统下的多线程遵循POSIX线程接口,称为 pthread.编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a.顺便说一下,Linux ...

  5. Verilog设计技巧实例及实现

    Verilog设计技巧实例及实现 1 引言 最近在刷HDLBits的过程中学习了一些Verilog的设计技巧,在这里予以整理.部分操作可能降低代码的可读性和Debug的难度,请大家根据实际情况进行使用 ...

  6. Codeforces Round #735 (Div. 2)

    这次的cf依旧掉分..... A题和B题在不懈死磕下瞎搞出来了,不过还是被C题卡住了... C. Mikasa 简述题意就是给定n和m,让n^0,n^1,n^2...,n^m,求着m+1个数中没有出现 ...

  7. CentOS部署多台服务器JDK(shell脚本部署)

    部署7台新服务器的jdk,数量不算多,但也不打算一台一台的部署,写了个脚本执行 [ #!/bin/bash# JDK 安装包名jdk_packge="jdk-8u162-linux-x64. ...

  8. Java——去掉小数点后面多余的0

    当小数点后位数过多,多余的0没有实际意义,根据业务需求需要去掉多余的0.后端存储浮点型数据一般会用到Bigdecimal 类型,可以调用相关方法去掉小数后多余0,然后转为string. public ...

  9. 在C#中对TCP客户端的状态封装详解

    引用地址: https://www.jb51.net/article/35689.htm

  10. 如何系统学习C 语言(中)之 结构体篇

    1,结构体 在前面我们知道变量和数组都可以用来存储数据,变量用来存储单个数据,数组可以用来存储一组同类型的数据,但你有没有发现--它们都只适合单一属性的数据.那现实生活中,很多对象都是具有多属性的.例 ...