• bzoj3811 玛里苟斯


    Description

    魔法之龙玛里苟斯最近在为加基森拍卖师的削弱而感到伤心,于是他想了一道数学题。
    S 是一个可重集合,S={a1,a2,…,an}。
    等概率随机取 S 的一个子集 A={ai1,…,aim}。
    计算出 A 中所有元素异或 x, 求 xk 的期望。 

    Input

    第一行两个正整数 n, k。
    以下 n 行每行一个整数,表示 ai。

    Output

    如果结果是整数,直接输出。如果结果是小数(显然这个小数是有限的),输出精确值(末尾不加多余的 0)。 

    Sample Input

    4 2
    0
    1
    2
    3

    Sample Output

    3.5

    HINT

    限制与约定
    1≤n≤100000,1≤k≤5,ai≥0。最终答案小于 2^63 。k=1,2,3,4,5 各自占用 20% 的数据

    正解:$dp$+线性基。

    $k=1$比较简单,考虑把单独计算每一位。

    如果有至少一个数这一位是$1$,那么很显然,这一位为$0$和为$1$的概率相等,都是$0.5$;否则这一位只可能是$0$。

    $k=2$其实差不多,但是我还是没想到。。

    考虑枚举异或以后的数的二进制任意两位的平方,当这两位的平方有贡献当且仅当这两位都是$1$。

    然后计算一下这两位都是$1$的概率,假设两位分别为$i,j$,那么这两位组合的期望就是$2^{i+j}*p$。

    $p$也比较好算,如果所有数在$i$和$j$两位都相等的话那么概率就是$0.5$,否则概率就是$0.25$。

    $k>=3$时,因为题目说答案小于$2^{63}$,那么每个数肯定最多只有$22$位。

    根据线性基的性质,$n$个数异或以后的数出现概率与线性基中这个数出现概率相同。

    假设线性基元素有$k$个,那么$n$个数异或以后每个数出现概率就是$frac{1}{2^{k}}$,于是我们直接写一个爆搜,搜出线性基的所有异或情况就行了。

      1 #include <bits/stdc++.h>
      2 #define il inline
      3 #define RG register
      4 #define ull unsigned long long
      5  
      6 using namespace std;
      7  
      8 ull a[100010];
      9 int n,k;
     10  
     11 il ull gi(){
     12   RG ull x=0,q=1; RG char ch=getchar();
     13   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
     14   if (ch=='-') q=-1,ch=getchar();
     15   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
     16   return q*x;
     17 }
     18  
     19 namespace solve1{
     20    
     21   ull ans;
     22    
     23   int main(){
     24     for (RG int i=1;i<=n;++i) ans|=a[i];
     25     printf("%llu",ans>>1);
     26     puts((ans&1)?".5":"");
     27     return 0;
     28   }
     29    
     30 }
     31  
     32 namespace solve2{
     33    
     34   ull ret,res,ans;
     35    
     36   int main(){
     37     for (RG int i=1;i<=n;++i) ret|=a[i];
     38     for (RG int i=0;i<32;++i)
     39       for (RG int j=0,fg=0;j<32;++j,fg=0)
     40     if ((ret>>i&1) && (ret>>j&1)){
     41       for (RG int p=1;p<=n;++p)
     42         if ((a[p]>>i&1)^(a[p]>>j&1)){ fg=1; break; }
     43       if (i+j-1-fg<0) ++res; else ans+=1llu<<(i+j-1-fg);
     44     }
     45     ans+=res>>1,printf("%llu",ans);
     46     puts((res&1)?".5":""); return 0;
     47   }
     48    
     49 }
     50  
     51 namespace solve3{
     52    
     53   ull p[30],tot,ans,rhl;
     54   int Sz;
     55    
     56   il ull qpow(RG ull a,RG int b){
     57     RG ull ans=1;
     58     while (b){
     59       if (b&1) ans*=a; a*=a,b>>=1;
     60     }
     61     return ans;
     62   }
     63    
     64   il void insert(RG ull x){
     65     for (RG int i=Sz;i>=0;--i){
     66       if (!(x>>i&1)) continue;
     67       if (!p[i]){ p[i]=x; break; }
     68       x^=p[i];
     69     }
     70     return;
     71   }
     72    
     73   il void dfs(RG int x,RG ull S){
     74     if (x>Sz){
     75       RG ull res=1;
     76       for (RG int i=1;i<k;++i) res*=S;
     77       if (res<rhl){
     78     res*=S,tot+=res;
     79     if (tot>=rhl) ans+=tot/rhl,tot%=rhl;
     80       } else{
     81     ans+=res/rhl*S,res%=rhl,res*=S,tot+=res;
     82     if (tot>=rhl) ans+=tot/rhl,tot%=rhl;
     83       }
     84       return;
     85     }
     86     dfs(x+1,S),dfs(x+1,S^p[x]); return;
     87   }
     88    
     89   int main(){
     90     if (k==3) Sz=21; if (k==4) Sz=15; if (k==5) Sz=12;
     91     for (RG int i=1;i<=n;++i) insert(a[i]);
     92     rhl=1<<(Sz+1),dfs(0,0),printf("%llu",ans);
     93     puts(tot?".5":""); return 0;
     94   }
     95    
     96 }
     97  
     98 int main(){
     99 #ifndef ONLINE_JUDGE
    100   freopen("maligous.in","r",stdin);
    101   freopen("maligous.out","w",stdout);
    102 #endif
    103   n=gi(),k=gi();
    104   for (RG int i=1;i<=n;++i) a[i]=gi();
    105   if (k==1) solve1::main();
    106   if (k==2) solve2::main();
    107   if (k>=3) solve3::main();
    108   return 0;
    109 }
  • 相关阅读:
    linux c dlopen加载动态链接库
    c++锁 测试 (gcc test.cpp -o test -lpthread)
    shell 清理目录下 超过一段时间的数据。
    大话存储学习笔记
    python总结
    正则表达式使用
    #linux shell#模拟日志生成过程
    深入理解Java虚拟机
    Nginx修改access.log日志时间格式
    mfcs100d.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7510875.html
Copyright © 2020-2023  润新知