【数学期望】【NOIP模拟赛】连续段的期望

原创 2016年08月29日 00:42:13

题目描述

小 N 最近学习了位运算,她发现2个数xor之后数的大小可能变大也可能变小,and之后都不会变大,or之后不会变小。于是她想算出以下的期望值:现在有N个数排成一排, 如果她随意选择一对 l,r并将下标在lr中间(包括l,r)的数(xor,and,or)之后,期望得到的值是多少呢?取出每一对l,r的概率都是相等的。小 G 认为这太 easy 了【这太imba了】,容易被你们水过去,因此你需要告诉他所有选择情况下,(xor,and,or)值的和。

输入

第一行1个正整数N
第二行N个非负整数代表数列。

输出

共两行六个数。 第一行3个数,分别表示xor的期望,and的期望,or的期望,保留3位小数。 第二行3个数,分别表示xor的和,and的和,or的和。

样例输入

2
4 5

样例输出

2.750 4.250 4.750
11 17 19

数据范围

30%数据中1N1000
对于另外的30%数据数列中只包含0和1
对于100%的数据1N100000,数列中的数109

样例解释

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=(4+1+1+5)/4=2.750。其他同理 。


算法一

对于前30%数据,考虑暴力枚举l后扫到r并统计答案,期望则是每种运算的和除以n^2,时间复杂度O(n2),期望得分30分。

算法二

对于只包含0和1的数列,考虑三种运算的性质。

对于xor运算
  • 一段区间内如果包含奇数个1,则区间xor和为1;
  • 如果包含偶数个1,则区间xor和为0。
  • 可以发现若rl,对于每个1,其能对答案贡献的区间为以这个1及以前所有连续的0为开始,以这个1和从这个1开始统计序号为奇数的1以及他们后面连续的0为结尾的区间。可分奇偶做。
  • 举个栗子:
    0,1,1,0,0,0,1,0,0,1,0,1
  • 对于第一个1,有贡献的区间开始为{1,2},有贡献的区间结尾为{7,8,9,12}。乘起来就是贡献为8。
  • 对于每个1,可以统计出其前后的连续0个数,从前向后扫描时,可以先处理后面所有有贡献的1的后面的0的后缀和。为处理r<l的情况,将前方统计乘2减去1的个数即可(l=r)。
对于and运算
  • 一段区间内如果包含0,则区间and和为0;
  • 一段区间内如果全为1,则区间and和为1。
  • 从前向后扫描连续为1的区间,这段区间对答案的贡献就是区间长度的平方。
对于or运算
  • 一段区间如果包含1,则区间or和为1;
  • 一段区间如果全为0,则区间or和为0。
  • 从前向后扫描连续为0的区间,则有区间长度平方的区间无贡献,总贡献为n2减去区间长度平方和。
  • 可在统计xor时顺便统计出来

时间复杂度O(n),期望得分30分。
结合算法一,期望得分60分。

算法三

其实出题人已经指了一条明路。容易发现,可以对数列中的数的二进制表示的每一位分别做算法二。因为xor,and,or这些运算分别为按位运算,各数位之间无影响。
时间复杂度O(32n),期望得分100分。

上代码。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct one{
    int fore, back;
}even[50001], odd[50001];
//从0开始序号为偶数和奇数的1
long long n, arr[100002], l1, l2, l3, a1, a2, a3, sufe[50000], sufo[50000];
//N,数列,当前位三种运算和,总和,序号为偶和奇的1的back后缀和
int main(){
    scanf("%lld", &n);
    for(int i=0;i<n;i++)
        scanf("%lld", &arr[i]);
    for(int k=0;k<=31;k++){
        //枚举k位
        (arr[n]=1)<<=k;
        //边界
        memset(odd, 0, sizeof odd); memset(even, 0, sizeof even); memset(sufe, 0, sizeof sufe); memset(sufo, 0, sizeof sufo);
        long long cnt=0, zeros=0; l1=l2=l3=0;
        //一的个数,连续0的个数
        for(int i=0;i<=n;i++){
            if(!(arr[i]&arr[n])) zeros++;
            else{
                l3+=zeros*zeros;
                //统计or和
                if(cnt&1)
                    odd[cnt>>1].fore=zeros+1, even[cnt>>1].back=zeros+1;
                else even[cnt>>1].fore=zeros+1, odd[(cnt>>1)-1].back=zeros+1;
                //奇偶分别处理,注意cnt
                cnt++; zeros=0;
            }
        }
        cnt--;
        sufe[cnt>>1]=even[cnt>>1].back;
        for(int i=(cnt>>1)-1;~i;i--)
            sufe[i]=sufe[i+1]+even[i].back;
        for(int i=0;i<=(cnt>>1);i++)
            l1+=even[i].fore*sufe[i];
        if(cnt&1){
            sufo[cnt>>1]=odd[cnt>>1].back;
            for(int i=(cnt>>1)-1;~i;i--)
                sufo[i]=sufo[i+1]+odd[i].back;
            for(int i=0;i<=(cnt>>1);i++)
                l1+=odd[i].fore*sufo[i];
        }
        else{
            sufo[(cnt>>1)-1]=odd[(cnt>>1)-1].back;
            for(int i=(cnt>>1)-2;i>=0;i--)
                sufo[i]=sufo[i+1]+odd[i].back;
            for(int i=0;i<(cnt>>1);i++)
                l1+=odd[i].fore*sufo[i];
        }
        //同样注意cnt的奇偶
        (l1*=2)-=cnt;
        l3=n*n-l3;
        long long ones=0; arr[n]=0;
        for(int i=0;i<=n;i++){
            if(arr[i]&(1ll<<k)) ones++;
            else l2+=ones*ones, ones=0;
        }
        //统计and和
        a1+=l1<<k; a2+=l2<<k; a3+=l3<<k;
        //统计第k位上的答案
    }
    printf("%.3lf %.3lf %.3lf\n%lld %lld %lld\n", double(a1)/(n*n), double(a2)/(n*n), double(a3)/(n*n), a1, a2, a3);
    return 0;
}

按位处理好强。

版权声明:本文为博主原创文章,未经博主允许不得转载。

数学期望DP小结

最近刚学了数学期望DP,还是蛮恶心的,但是相比于其他DP还是比较好想的,主要思路和线性DP类似,主要注意的是概率计算利用加法原理加和的方式,还要注意避免数组下标为负的情况,需要进行平移。 Tyvj18...

Play the Dice(数学期望)

题目大意:给你一发骰子,有n个面,掷骰子到第i个面时得到ai的钱,有时某些面bi,还可以让你再掷一次骰子,问最后可以获得的钱期望是多少? 设ans为当前得到的钱的期望 则只掷一次,期望是sum=∑...

美国12岁男孩智商超过爱因斯坦 欲挑战相对论

雅各布・巴内特   中新网3月26日电 据外国媒体报道,在美国有一名12岁的小男孩,piastre capelli ghd,他的智商比爱因斯坦还高,达170。目前,他正在印第安那大学学习,导师们正安排...

Lightoj 1027 概率期望

Problem: 概率期望 Analyse: 非常经典的带有递归实现,的方程期望式子. E为期望,z为正数个数,zp为正数平均值,f为负数个数,fp为负数平均值. z∗zpn+f∗fp+En=...

北师大珠海分校2016国庆欢乐赛题解

Amazing Score 这题长得跟基本的作业题很像,每次输入12个数,奇数位为学分a,偶数位为分数b,总的加权平均分为,然后当b小于60的时候特判一下,整组分数记为0即可 #includein...

2017GDCPC题解(未完)

Problem A:Open Box题目大意:给一把锁,锁的密码是9394,输入4个字符表示该锁每一位密码现在所在的位置,问最少需要多少次操作可以到9394,密码锁是旋转的0-9成环。算法思路:水题,...

东北酱油 模拟赛 期望dp

自动取款机   【问题描述】      小沈阳在小品里说过:“人生最痛苦的事情是人死了,钱还没花了”。 于是小宋(80岁)决定要将所有的储蓄从ATM机中取出花光。 小宋忘记了她有多少存款(银行卡密码她...
  • zjq_01
  • zjq_01
  • 2017年06月06日 19:27
  • 145

[NOIP 2016] 换教室:数学期望,DP

题意:一共有v间教室,e条有长度的双向通道,可能有重边和自环(v≤300,e≤90000)。n节课(n≤2000),每节课有两间教室可选,默认为c[i],可申请更换为d[i],申请要么通过要么不通过,...

【NOIP2017提高A组冲刺11.2】救赎(数学期望)

Description“是的。”我回答,“我不会忘记你。在森林里我会一点点记起往日的世界。要记起的大概很多很多:各种人、各种场所、各种光、各种歌曲……” ——村上春树《世界尽头与冷酷仙境》在没有心存...

熊猫人之谜主题模拟赛for noip

  • 2013年04月06日 12:06
  • 535KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【数学期望】【NOIP模拟赛】连续段的期望
举报原因:
原因补充:

(最多只允许输入30个字)