• bzoj3811 玛里苟斯


    分三种情况讨论

    k=1时,对于每一位而言,只要有一个数这一位是1,那么这个就有0.5的概率是1,选他就是1,不选就是0,有第二个的话,在第一个选或不选的前提下,也各有0.5的几率选或不选,0和1的概率还是一半一半。所以无论有几个,只要有任意一个数该位不得0,期望就是(1<<i)/2。所以我们只需要把所有的或起来除以二即可。

    k=2时,我们需要记录每两位之间的贡献,如果所有的数这两位都一样而且有都是1的数,那么这两位作出的贡献就是(1<<i+j)/2,

    如果有不一样的,那么贡献就是(1<<i+j)/4,

    k>=3时,我们发现现在的异或和最大是(1<<22),因为题目保证答案在(1<<63)内,所以我们状压直接暴力乱搞就好了,因为线性基的期望就是原数组的期望。然而我并不会理性证明,只能感性理解

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<vector>
     7 #define LL unsigned long long
     8 #define N 100500
     9 using namespace std;
    10 int n,m,p[66],bo[66];
    11 LL a[N],ANS,res;
    12 vector<int> v;
    13 int main(){
    14     scanf("%d%d",&n,&m);
    15     for(int i=1;i<=n;i++)scanf("%llu",&a[i]);
    16     if(m==1){
    17         LL ans=0;
    18         for(int i=1;i<=n;i++)ans|=a[i];
    19         if(ans&1ll)printf("%llu.5
    ",ans>>1ll);
    20         else printf("%llu
    ",ans>>1ll);
    21     }
    22     else if(m==2){
    23         LL ans=0;
    24         for(int i=1;i<=n;i++)ans|=a[i];
    25         for(int i=0;i<=31;i++)if(ans&(1ll<<i))bo[i]=1;
    26         for(int i=0;i<=31;i++)if(bo[i]){
    27             for(int j=0;j<=31;j++)if(bo[j]){
    28                 bool flag=0;
    29                 for(int k=1;k<=n;k++)if(((a[k]>>i)&1)!=((a[k]>>j)&1)){flag=1;break;}
    30                 if(i+j-1-flag<0)res++;
    31                 else ANS+=1ll<<i+j-1-flag;
    32             }
    33         }
    34         ANS+=res>>1ll;res&=1ll;
    35         printf("%llu",ANS);
    36         if(res)printf(".5
    ");
    37     }
    38     else{
    39         for(int i=1;i<=n;i++)
    40             for(int j=23;~j;j--)if(a[i]&(1ll<<j)){
    41                 if(p[j])a[i]^=a[p[j]];
    42                 else{v.push_back(a[i]);p[j]=i;break;}
    43             }
    44         int nn=v.size();
    45         for(int i=0;i<(1<<nn);i++){
    46             LL val=0,a=0,b=1;
    47             for(int j=0;j<nn;j++)if(i&(1<<j))val^=v[j];
    48             for(int j=1;j<=m;j++){
    49                 a=a*val;b=b*val;
    50                 a+=(b>>nn);b&=(1ll<<nn)-1;
    51             }
    52             ANS+=a;res+=b;
    53             ANS+=res>>nn;res&=(1ll<<nn)-1;
    54         }
    55         printf("%llu",ANS);
    56         if(res)printf(".5
    ");
    57     }
    58     return 0;
    59 }
    View Code
  • 相关阅读:
    chrome 插件备份
    github下载单个文件
    idea插件备份
    外卖类应用的竞争与趋势
    使用终端和Java API对hbase进行增删改查操作
    分布式文件系统的布局、文件查找
    Java上机实验报告(4)
    Java上机实验报告(3)
    Java上机实验报告(2)
    Java上机实验报告(1)
  • 原文地址:https://www.cnblogs.com/Ren-Ivan/p/8379362.html
Copyright © 2020-2023  润新知