Freda发明了传呼机之后,rainbow进一步改进了传呼机发送信息所使用的信号。由于现在是数字、信息时代,rainbow发明的信号用N个自然数表示。为了避免两个人的对话被大坏蛋VariantF偷听T_T,rainbow把对话分成A、B、C三部分,分别用a、b、c三个密码加密。现在Freda接到了rainbow的信息,她的首要工作就是解密。Freda了解到,这三部分的密码计算方式如下:

在1~N这N个数中,等概率地选取两个数l、r,如果l>r,则交换l、r。把信号中的第l个数到第r个数取出来,构成一个数列P。

A部分对话的密码是数列P的xor和的数学期望值。xor和就是数列P中各个数异或之后得到的数; xor和的期望就是对于所有可能选取的l、r,所得到的数列的xor和的平均数。

B部分对话的密码是数列P的and和的期望,定义类似于xor和。

C部分对话的密码是数列P的or和的期望,定义类似于xor和。

输入

第一行一个正整数N。 第二行N个自然数,表示Freda接到的信号。

输出

一行三个实数,分别表示xor和、and和、or和的期望,四舍五入保留3位小数,相邻两个实数之间用一个空格隔开。

样例输入1

2 4 5

样例输入2

3 1 0 1

样例输出1

2.750 4.250 4.750

样例输出2

0.667 0.222 0.889

C++内容:

#include <iostream>
#include <vector>
#include <cmath>
#include <iomanip>

using namespace std;

// 计算xor和的期望
double calculateXorExpectation(vector<int>& nums) {
    int n = nums.size();
    double expectation = 0;
    for (int l = 1; l <= n; l++) {
        for (int r = l; r <= n; r++) {
            int xorSum = 0;
            for (int i = l; i <= r; i++) {
                xorSum ^= nums[i - 1];
            }
            expectation += xorSum;
        }
    }
    expectation /= (n * (n + 1) / 2);
    return expectation;
}

// 计算and和的期望
double calculateAndExpectation(vector<int>& nums) {
    int n = nums.size();
    double expectation = 0;
    for (int l = 1; l <= n; l++) {
        for (int r = l; r <= n; r++) {
            int andSum = nums[l - 1];
            for (int i = l + 1; i <= r; i++) {
                andSum &= nums[i - 1];
            }
            expectation += andSum;
        }
    }
    expectation /= (n * (n + 1) / 2);
    return expectation;
}

// 计算or和的期望
double calculateOrExpectation(vector<int>& nums) {
    int n = nums.size();
    double expectation = 0;
    for (int l = 1; l <= n; l++) {
        for (int r = l; r <= n; r++) {
            int orSum = nums[l - 1];
            for (int i = l + 1; i <= r; i++) {
                orSum |= nums[i - 1];
            }
            expectation += orSum;
        }
    }
    expectation /= (n * (n + 1) / 2);
    return expectation;
}

int main() {
    int N;
    cin >> N;
    vector<int> nums(N);
    for (int i = 0; i < N; i++) {
        cin >> nums[i];
    }
    double xorExpectation = calculateXorExpectation(nums);
    double andExpectation = calculateAndExpectation(nums);
    double orExpectation = calculateOrExpectation(nums);
    cout << fixed << setprecision(3) << xorExpectation << ' ' << andExpectation << ' ' << orExpectation << endl;
    return 0;
}

原文地址: https://www.cveoy.top/t/topic/pigD 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录