CF 996 F. Game (思维、 数学期望)

题目:传送门

题意:给一个整数 n (1 <= n <= 18),输入 2^n 个数,编号为 0~2^n - 1(即数组 c ),起初有一个整数 statu,它的前 n 位二进制位都等于 -1,现在有A和B两人,共操作 n 次,每次操作等概率选择 satu 一个二进制位为 -1 的位,将它变为 0 或者1,最终得到 c[statu] 的值, A 想让这个值尽可能大, B 想让这个值尽可能小。现在有 r (0 <= r <= 2^18) 次修改,每次修改操作输入两个数, x,val,表示将 c[x] 重新赋值为 val,输出 r + 1 行,分别表示,最终得到的值的期望。

思路:因为 A 和 B 想要的是相反的,那么每个二进制位等于 0 和等于 1 的概率是相等的,每个数字被取到的概率也是相等的,即 statu 等于 [ 0, 2^n - 1 ] 的概率是相等的,最终每个 c[i] 被取到的概率都是 1 / 2^n,答案就是相当于求平均值。

#include <bits/stdc++.h>
#define LL long long
#define mem(i, j) memset(i, j, sizeof(i))
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define dep(i, j, k) for(int i = k; i >= j; i--)
#define pb push_back
#define make make_pair
#define INF INT_MAX
#define inf LLONG_MAX
#define PI acos(-1)
using namespace std;

const int N = 1e6 + 5;

int a[N];

int main() {
    int n, r;
    scanf("%d %d", &n, &r);
    LL ans = 0LL;
    rep(i, 0, (1 << n) - 1) scanf("%d", &a[i]), ans += a[i];

    printf("%.8f
", (double)((double)(ans) / (double)((1 << n))));

    rep(i, 1, r) {
        int x, val;
        scanf("%d %d", &x, &val);
        ans -= a[x]; a[x] = val; ans += a[x];
        printf("%.8f
", ((double)(ans) / (double)((1 << n))));
    }

    return 0;
}
一步一步,永不停息
原文地址:https://www.cnblogs.com/Willems/p/12539444.html