zoukankan      html  css  js  c++  java
  • 【清华集训2014】玛里苟斯

    UOJ36【清华集训2014】玛里苟斯

    给定序列 (a),每个元素有 (frac{1}{2}) 的概率被选择,设 (x) 表示被选择的元素的异或和,求 (x^k) 的期望。

    (nle 10^5,kle 5,a_ige 0)

    保证答案小于 (2^{63})

    Solution

    假设 (kge 3),那么可以注意到值域会大概是 (sqrt{2^{63}}) 这个级别。

    所以线性基很小,由于每种值的出现次数都相同(线性基的推论)所以每种值对答案的贡献都是 (frac{x^k}{2^{cnt}})

    否则如果 (k=1),那么只需要考虑每一位的贡献。

    (k=2) 就考虑一下每两位的贡献即可。

    当然,仍然只需要保留线性基的元素,这样的话就不会除非常大的数。

    然后这个题有结论,答案最多只能是 (x.5),所以特判一下即可

    (Code:)

    #include<bits/stdc++.h>
    using namespace std ;
    #define Next( i, x ) for( register int i = head[x]; i; i = e[i].next )
    #define rep( i, s, t ) for( register int i = (s); i <= (t); ++ i )
    #define drep( i, s, t ) for( register int i = (t); i >= (s); -- i )
    #define re register
    #define int __int128
    int gi() {
    	char cc = getchar() ; int cn = 0, flus = 1 ;
    	while( cc < '0' || cc > '9' ) {  if( cc == '-' ) flus = - flus ; cc = getchar() ; }
    	while( cc >= '0' && cc <= '9' )  cn = cn * 10 + cc - '0', cc = getchar() ;
    	return cn * flus ;
    }
    const int N = 1e5 + 5 ; 
    const int M = 100 + 5 ; 
    int n, K, cnt, tmp[M], s[M], C[M][M], fc[150] ;
    int Ans ; 
    void insert(int x) {
    	drep( i, 0, 64 ) if((x >> i) & 1) {
    		if( tmp[i] ) x ^= tmp[i] ;
    		else tmp[i] = x, x = 0 ;
    	}
    }
    int fpow(int x, int k) {
    	int ans = 1, base = x ;
    	while(k) {
    		if(k & 1) ans = ans * base ;
    		base = base * base, k >>= 1 ;
    	} return ans ;
    }
    void Dfs(int x, int S) {
    	if(x == cnt + 1) return Ans += fpow(S, K), void() ; 
    	Dfs(x + 1, S), Dfs(x + 1, S ^ s[x]) ;
    }
    void write() {
    	int iv = (1ll << cnt) ; 
    	int d = Ans / iv ; 
    	printf("%llu", (unsigned long long)(d) ) ;
    	if( d * iv < Ans ) printf(".5") ; 
    }
    void Solve1() {
    	Dfs(1, 0), write() ; 
    }
    void Solve2() {
    	fc[0] = 1 ; rep( i, 1, 100 ) fc[i] = fc[i - 1] * 2 ; 
    	rep( i, 0, 62 ) rep( j, 0, 62 ) {
    		if( i + j > 100 ) continue ; 
    		int a = 0, b = 0, c = 0, r = 0, d = fc[i + j] ;
    		rep( k, 1, cnt ) if((s[k] >> i) & 1) ++ a ;
    		rep( k, 1, cnt ) if((s[k] >> j) & 1) ++ b ;
    		rep( k, 1, cnt ) if(((s[k] >> i) & 1) && ((s[k] >> j) & 1)) ++ c ; 
    		a -= c, b -= c ; 
    		if( (!a) && (!c) && (!b) ) continue ;  
    		rep( k, 0, c ) {
    			int f = 0, g = 0 ;
    			if(k & 1) {
    				rep(l, 0, a) if(!(l & 1)) f += C[a][l] ;
    				rep(l, 0, b) if(!(l & 1)) g += C[b][l] ;
    				r += C[c][k] * f * g ; 
    			}
    			else {
    				rep(l, 0, a) if((l & 1)) f += C[a][l] ;
    				rep(l, 0, b) if((l & 1)) g += C[b][l] ;
    				r += C[c][k] * f * g ; 
    			}
    		} 
    		Ans += d * r * (1ll << (cnt - a - b - c)) ; 
    	} write() ; 
    }
    void Solve3() {
    	rep( j, 1, cnt ) Ans |= s[j] ;
    	cnt = 1 ; write() ; 
    }
    signed main()
    {
    	n = gi(), K = gi() ; int x ;
    	rep( i, 1, n ) x = gi(), insert(x) ; 
    	rep( i, 0, 64 ) if(tmp[i]) s[++ cnt] = tmp[i] ;
    	C[0][0] = 1 ; 
    	rep( i, 1, 64 ) rep( j, 0, 64 ) C[i][j] = (!j) ? 1 : (C[i - 1][j - 1] + C[i - 1][j]) ; 
    	if( K >= 3 ) Solve1() ; 
    	else if( K == 2 ) Solve2() ;
    	else Solve3() ; 
    	return 0 ;
    }
    
  • 相关阅读:
    机器学习(深度学习)
    机器学习(六)
    机器学习一-三
    Leetcode 90. 子集 II dfs
    Leetcode 83. 删除排序链表中的重复元素 链表操作
    《算法竞赛进阶指南》 第二章 Acwing 139. 回文子串的最大长度
    LeetCode 80. 删除有序数组中的重复项 II 双指针
    LeetCode 86 分割链表
    《算法竞赛进阶指南》 第二章 Acwing 138. 兔子与兔子 哈希
    《算法竞赛进阶指南》 第二章 Acwing 137. 雪花雪花雪花 哈希
  • 原文地址:https://www.cnblogs.com/Soulist/p/13784372.html
Copyright © 2011-2022 走看看