2015弱校联萌十一大决战之背水一战 Binary Operations 状态压缩dp

本文介绍了一道关于计算随机选择连续子序列进行位运算(AND、OR、XOR)期望值的问题,通过状态压缩DP的方法解决,实现了高效计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://www.bnuoj.com/v3/problem_show.php?pid=24250

Bob has a sequence of N integers. They are so attractive, that Alice begs to have a continued part of it(a continued part here also means a continued subsequence). However, Bob only allows Alice to chose it randomly. Can you give the expectation of the result of the bitwise AND, OR, XOR of all the chosen numbers?

Input


First line of the input is a single integer T(1 <= T <= 50), indicating there are T test cases.

The first line of each test case contains a single number N(1 <= N <= 50000).

The second line contains N integers, indicating the sequence.

All the N integers are fit in [0, 10^9].

Output

For each test case, print "Case #t: a b c" , in which t is the number of the test case starting from 1, a is the expectation of the bitwise AND, b is the expectation of OR and c is the expectation of XOR.

Round the answer to the sixth digit after the decimal point.

Sample Input

3
2
1 2
3
1 2 3
3
2 3 4

Sample Output

Case #1: 1.000000 2.000000 2.000000
Case #2: 1.333333 2.500000 1.666667
Case #3: 1.833333 4.333333 3.666667

Hint

AND is a binary operation, performed on two numbers in binary notation. First, the shorter number is prepended with leading zeroes until both numbers have the same number of digits (in binary). Then, the result is calculated as follows: for each bit where the numbers are both 1 the result has 1 in its binary representation. It has 0 in all other positions.

OR is a binary operation, performed on two numbers in binary notation. First, the shorter number is prepended with leading zeroes until both numbers have the same number of digits (in binary). Then, the result is calculated as follows: for each bit where the numbers are both 0 the result has 0 in its binary representation. It has 1 in all other positions.

XOR is a binary operation, performed on two numbers in binary notation. First, the shorter number is prepended with leading zeroes until both numbers have the same number of digits (in binary). Then, the result is calculated as follows: for each bit where the numbers differ the result has 1 in its binary representation. It has 0 in all other positions.

Source

/**
2015弱校联萌十一大决战之背水一战 Binary Operations  状态压缩dp
题目大意:给定一个序列,求出随意选择一段连续的序列得到该序列元素的且、或、异或的值得期望是多少
解题思路:dp[k][i] 表示第k位以第i个元素为结尾的序列有多少个1,由于期望具有可加性,那么dp一下就可以了,状体转移方程详见代码
*/
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long LL;
const int maxn=50500;
int n,a[maxn],dpand[maxn],dpor[maxn],dpxor[maxn];
int main()
{
    int T,tt=0;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=1; i<=n; i++)scanf("%d",&a[i]);
        double cntand=0.0,cntor=0.0,cntxor=0.0;
        for(int k=0; k<=30; k++)
        {
            memset(dpand,0,sizeof(dpand));
            memset(dpor,0,sizeof(dpor));
            memset(dpxor,0,sizeof(dpxor));
            if((1LL<<k)&a[1])
            {
                dpand[1]=1;
                dpor[1]=1;
                dpxor[1]=1;
            }
            LL sumand=dpand[1];
            LL sumor=dpor[1];
            LL sumxor=dpxor[1];
            for(int i=2; i<=n; i++)
            {
                if((1LL<<k)&a[i])
                {
                    dpand[i]=dpand[i-1]+1;
                    dpor[i]=i;
                    dpxor[i]=i-dpxor[i-1];
                }
                else
                {
                    dpand[i]=0;
                    dpor[i]=dpor[i-1];
                    dpxor[i]=dpxor[i-1];
                }
                sumand+=dpand[i];
                sumor+=dpor[i];
                sumxor+=dpxor[i];
            }
            cntand+=2.0*(1LL<<k)*sumand/((LL)n*n+n);
            cntor+=2.0*(1LL<<k)*sumor/((LL)n*n+n);
            cntxor+=2.0*(1LL<<k)*sumxor/((LL)n*n+n);
        }
        printf("Case #%d: %.6lf %.6lf %.6lf\n",++tt,cntand,cntor,cntxor);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值