Address
https://www.lydsy.com/JudgeOnline/problem.php?id=4036
Solution
注:下面的
和幂,如果运算的对象是序列,则表示或卷积。
(即
)
同时下面
表示选数
的概率,即题目中的输入。
考虑
表示操作了
次之后数变成
的概率。
那么容易得到
以及:
根据或卷积的定义,易得 。
于是,我们设 为变成 的期望步数。
那么我们得到:
我们对 求快速莫比乌斯变换 。
转化成:
将 求快速莫比乌斯反演后,答案为 。
无解的情况:如果无解,那么对于任意的 都满足 ,这时候就能推出 。故当 时无解。
复杂度 。
Code
代码非常短。
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define For(i, a, b) for (i = a; i <= b; i++)
using namespace std;
const int N = 1048888;
const double eps = 1e-8;
int n, Cm;
double f[N];
void FMT(double *f, int op)
{
int i, j;
For (i, 1, n) For (j, 0, Cm)
if (!((j >> i - 1) & 1))
f[j | (1 << i - 1)] += f[j] * op;
}
int main()
{
int i;
cin >> n;
Cm = (1 << n) - 1;
For (i, 0, Cm) scanf("%lf", &f[i]);
FMT(f, 1);
For (i, 0, Cm)
f[i] = fabs(f[i] - 1.0) < eps ? 0 : -1.0 / (1.0 - f[i]);
FMT(f, -1);
if (f[Cm] < eps) puts("INF");
else printf("%.10lf\n", f[Cm]);
return 0;
}