zoukankan      html  css  js  c++  java
  • 《算法竞赛进阶指南》0x38概率与数学期望 Rainbow

    题目链接:https://www.acwing.com/problem/content/218/

    题目给出n个数,要求求从中任意取出一个区间的数求异或和、or和、and和的数学期望。当每个数只有0和1的时候是容易求的,此时只需要把这个int数分解成二进制数对每一位进行求解即可。

    其中异或和的计算中,c1是从r-1开始向前扫描的[l,r-1]段有偶数个1的l取值的集合的大小,c2的定义与 c1相似,只是是奇数个1.如果扫描到当前的数是0,那么只需要保证c1++,如果当前的数是1的话就需要交换c1和c2并且c2的数量++。

    代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int maxn = 100010;
    int a[maxn],b[maxn];
    int n;
    double ansxor,ansor,ansand;
    void Rainbow(int k){//对每个数的第k位进行处理 
        int last[2]={0,0},c1=0,c2=0;//last表示上一个0/1在哪个给定的数的第k位出现 
        double w=(double)(1<<k)/n/n; 
        for(int i=1;i<=n;i++){
            b[i]=((a[i]>>k)&1);
            if(b[i]){//区间长度为1的情况 
                ansxor+=w;
                ansand+=w;
                ansor+=w;
            }
            //区间长度不为1的情况 
            if(!b[i]){
                ansor+=w*last[1]*2;
                ansxor+=w*c2*2;
            }else{
                ansand+=(i-last[0]-1)*w*2;
                ansor+=w*(i-1)*2;
                ansxor+=w*c1*2;
            }
            //为下一位左右右端点的情况计算新的c1,c2 
            c1++; 
            if(b[i])swap(c1,c2);
            last[b[i]]=i;
        }
    }
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=0;i<31;i++)Rainbow(i);//1e9数据之内最多有31位
        printf("%.3lf %.3lf %.3lf
    ",ansxor,ansand,ansor);
        return 0; 
    } 
  • 相关阅读:
    Html页面添加百度地图
    Redis Sentinel主从高可用方案
    redis分布式锁-SETNX实现
    使用RestTemplate访问restful服务时遇到的问题
    RestTemplate
    webservice服务器端获取request对象的三种方式
    Apache软件基金会项目百度百科链接
    JAX-RPC 与 JAX-WS 的比较
    angular+ionic前后端分离开发项目中的使用
    WebService之soap类型的服务和rest类型的服务
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13288441.html
Copyright © 2011-2022 走看看