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

样例解释

样例1共包含四种可能的l、r:

l, r xor和 and和 or和 1,1 4 4 4 1,2 1 4 5 2,1 1 4 5 2,2 5 5 5

以上每一对l、r出现的概率均相同,因此分别对xor和、and和、or和取平均数就是数学期望值。

C++内容:

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;

int main() {
    int N;
    cin >> N;
    vector<int> signal(N);
    for (int i = 0; i < N; ++i) {
        cin >> signal[i];
    }

    double xorSum = 0.0;
    double andSum = 0.0;
    double orSum = 0.0;

    for (int l = 0; l < N; ++l) {
        for (int r = l; r < N; ++r) {
            vector<int> subSignal(signal.begin() + l, signal.begin() + r + 1);
            int xorResult = subSignal[0];
            int andResult = subSignal[0];
            int orResult = subSignal[0];
            for (int i = 1; i < subSignal.size(); ++i) {
                xorResult ^= subSignal[i];
                andResult &= subSignal[i];
                orResult |= subSignal[i];
            }
            xorSum += xorResult;
            andSum += andResult;
            orSum += orResult;
        }
    }

    double xorExpectation = xorSum / (N * (N + 1) / 2);
    double andExpectation = andSum / (N * (N + 1) / 2);
    double orExpectation = orSum / (N * (N + 1) / 2);

    cout << fixed << setprecision(3) << xorExpectation << " " << andExpectation << " " << orExpectation << endl;

    return 0;
}

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

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