@description@

给定一个值域在 [0, 2^N) 的随机数生成器,给定参数 A[0...2^N-1]。

该生成器有 \(\frac{A_i}{\sum A}\) 的概率生成 i,每次生成都是独立的。

现在有一个 X,初始为 0。每次操作生成一个随机数 v 并将 X 异或 v。

对于每一个 i ∈ [0, 2^N),求期望多少次操作 X 第一次等于 i。

原题题面

@solution@

不难想到期望 dp。定义 dp[i] 表示到达 i 的期望次数,则:

\[dp[0] = 0 \\
dp[i] = (\sum_{j=0}^{2^N - 1}dp[j]\times p[i\oplus j]) + 1
\]

其中 \(p[i] = \frac{A_i}{\sum A}\)。

朴素做法是高斯消元。显然过不了。

对于高斯消元的常规优化是利用转移的图结构(比如 DAG,链或者树),但是这个题转移的图是完全图,做不到。

怎么办?观察转移式的结构,发现它其实是异或卷积。于是我们尝试走生成函数那一套。

如果用生成函数的记法,又可以将其记作 \(dp\oplus P + I = dp + k\times T\),其中 \(I[i] = 1, T[i] = [i = 0]\),\(k\) 是一个未知数。

注意当 n = 0 卷积是不成立的,所以需要在末尾填上一项 \(k\times T\)。

变一下形得到 \(dp\oplus (T - P) = I - k\times T\),两边同时进行 fwt 得到 \(dp'\times (T - P)' = I' - k\times T'\)。

注意到 \((T - P)'\) 的第 0 项始终为 0(根据 fwt 的定义可知),故 \(I' - k\times T'\) 的第 0 项也为 0,由此可以解出 k。

但是这样一来我们又不知道 \(dp'[0]\) 的值为多少,再次设未知数为 q。进行逆变换时把未知数代进去一起运算就可以了。

然后 \(dp\) 数列就可以表示成含 q 的一次函数,而根据 \(dp[0] = 0\) 可以反解出 q,于是 \(dp\) 数列就解出来了。

@accepted code@

#include <cstdio>

const int MOD = 998244353;
const int INV2 = (MOD + 1) >> 1; int add(int x, int y) {return (x + y >= MOD ? x + y - MOD : x + y);}
int sub(int x, int y) {return (x - y < 0 ? x - y + MOD : x - y);}
int mul(int x, int y) {return 1LL*x*y%MOD;} int pow_mod(int b, int p) {
int ret = 1;
for(int i=p;i;i>>=1,b=mul(b,b))
if( i & 1 ) ret = mul(ret,b);
return ret;
} struct node{
int k, b;
node() : k(0), b(0) {}
node(int _k, int _b) : k(_k), b(_b) {}
int get(int x) {return add(mul(k, x), b);}
friend node operator + (node a, node b) {
return node(add(a.k, b.k), add(a.b, b.b));
}
friend node operator - (node a, node b) {
return node(sub(a.k, b.k), sub(a.b, b.b));
}
friend node operator * (node a, int k) {
return node(mul(a.k, k), mul(a.b, k));
}
friend node operator / (node a, int k) {
return a * pow_mod(k, MOD - 2);
}
}; void fwt(node *A, int m, int type) {
int n = (1 << m), f = (type == 1 ? 1 : INV2);
for(int i=1;i<=m;i++) {
int s = (1 << i), t = (s >> 1);
for(int j=0;j<n;j+=s)
for(int k=0;k<t;k++) {
node x = A[j+k], y = A[j+k+t];
A[j+k] = (x + y)*f, A[j+k+t] = (x - y)*f;
}
}
} node A[1<<18], B[1<<18], C[1<<18], f[1<<18]; int main() {
int N, M, S = 0; scanf("%d", &N), M = (1 << N);
for(int i=0;i<M;i++) scanf("%d", &A[i].b), S = add(S, A[i].b);
S = pow_mod(S, MOD - 2);
for(int i=0;i<M;i++) A[i].b = sub(i == 0 ? 1 : 0, mul(A[i].b, S));
for(int i=0;i<M;i++) B[i].b = 1;
C[0].b = MOD - 1;
fwt(A, N, 1), fwt(B, N, 1), fwt(C, N, 1);
int tmp = mul(B[0].b, pow_mod(C[0].b, MOD-2));
for(int i=1;i<M;i++)
f[i] = (B[i] - C[i]*tmp) / A[i].b;
f[0].k = 1; fwt(f, N, -1);
int x = sub(0, mul(pow_mod(f[0].k, MOD-2), f[0].b));
for(int i=0;i<M;i++) printf("%d\n", f[i].get(x));
}

@details@

感觉我的做法很像是乱搞。。。不过我也不大清楚官方正解是啥子。。。

@atcoder - 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. [AGC034F]RNG and XOR

    题目   点这里看题目. 分析   第一步可以将\(A\)数组转化成概率\(P(j)\):每一步操作异或\(j\)的概率.   接着发现,\(x\)从\(0\)变成\(i\)的期望等于\(x\)从\( ...

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

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

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

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

  5. AtCoder abc 141 F - Xor Sum 3(线性基)

    传送门 题意: 给出\(n\)个数\(a_i\),现在要将其分为两堆,使得这两堆数的异或和相加最大. 思路: 考虑线性基贪心求解. 但直接上线性基求出一组的答案是行不通的,原因之后会说. 注意到如果二 ...

  6. [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$的期望步 ...

  7. GOOD BYE OI

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

  8. 【AtCoder】AGC034

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

  9. Atcoder Beginner Contest 121 D - XOR World(区间异或和)

    题目链接:https://atcoder.jp/contests/abc121/tasks/abc121_d 题目很裸(Atcoder好像都比较裸 就给一个区间求异或和 n到1e12 肯定不能O(n) ...

随机推荐

  1. select 下拉框样式修改 option文字居右

    select { direction: rtl; /*Chrome和Firefox里面的边框是不一样的,所以复写了一下*/ border: solid 1px #000; /*很关键:将默认的sele ...

  2. Null passed to a callee that requires a non-null argument

    OC中定义的方法参数默认是不为空的,如果能够为空需要手动指定__nullable ,我想这个警告是提示开发者警惕可能空参数

  3. PHP的图像函数

    imagecreate() 和 imagecreatetruecolor() 函数用于创建一幅空白图像. imagedestroy() 函数用于销毁图像资源. imagecreate() 如果我们要对 ...

  4. Python __str__(self)

    python 在打印一个实例化对象时,打印的是对象的地址,比如:<__main__.Workers object at 0x00000000255A9AC8> 而__str__(self) ...

  5. 关于pytest使用allure生成报告时,报一堆警告和缺少XX模块

    因为最新的pytest 支持*.josn的用例报告,卸载旧的模块使用新的即可: 需要移除旧模块:pip uninstall pytest-allure-adaptor, 并安装:pip install ...

  6. eatwhatApp开发实战(一)

    开发背景: 当你想用抛硬币来决定事情的时候,那么硬币抛起的瞬间,你就有答案了.一样的,吃啥?eatwhat点开,按钮一点,你就可以知道你中午要吃啥. 话不多说,项目开发走起 ADT点开,New==&g ...

  7. 移动端适配-rem(新)

    概念 对于移动端开发来说,无可避免的就是直面各种设备不同分辨率和不同DPR(设备像素比)的问题,在此忽略其他兼容性问题的探讨. 移动端像素 设备像素(dp),也叫物理像素.指设备能控制显示的最小物理单 ...

  8. Linux题目

    1.删除某目录下所有文件,只保留指定文件. 例:假设/abc文件夹下有a1.a2....a10文件,保留a5和a6文件,其他全部删除 [root@localhost abc]# touch a{1.. ...

  9. 【JAVA习题十五】两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。

    package erase; public class 选人比赛 { public static void main(String[] args) { // TODO Auto-generated m ...

  10. jchdl - RTL Data Types

    https://mp.weixin.qq.com/s/hWYW1Bn---WhpwVu2e98qA   一. Bit ​​ 类结构如下: ​​   主要属性: value: bit的值,只支持0,1, ...