zoukankan      html  css  js  c++  java
  • BZOJ3811玛里苟斯

    Description

    从一个序列里面选择一些数异或起来,求所有异或方案的答案的 (k) 次方的期望值

    (n le 100000,1le k le 5)

    Solution

    对于 (k=1) 的情况,对于每一位分开考虑

    如果至少有一个数的当前位是 (1) 的,那么有一半的可能性为 (0)

    也就是如果一个异或方案为 (0) 那么选择其补就能能得到为 (1) 的结果

    使用期望的线性性即可

    对于 (k>1) 的部分,平方的时候二进制位的贡献并不独立,所以需要分开考虑

    发现题目中说的 (ans le 2^{63}),那么对于 (k ge 3) 的,对原序列建立线性基,其大小不会超过 (63/3=21)

    原序列能异或出来的数,每个会重复 (2^{n-siz}) 次,所以期望就是 (frac {sum}{2^k})

    所以这个部分 (dfs) 或者直接状压即可

    剩余的 (k=2) 的部分考虑平方的本质是两个位相乘进行贡献,考虑两个带 (1) 的位置是不是能进行贡献

    如果是一个数中两个位置不同,注意这里要再除掉 (2) 因为这里的异或方案不足

    Code

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    namespace yspm{
    	#define ul unsigned long long
    	inline ul read()
    	{
    		ul res=0; char k;
    		while(!isdigit(k=getchar()));
    		while(isdigit(k)) res=res*10+k-'0',k=getchar();
    		return res;
    	}
    	int p[30],s,siz,n,m,pos,las,cnt;
    	ul ans,a[100010];
    	inline void insert(int x)
    	{
    		for(int i=siz;i>=0;--i)
    		{
    			if(!(x>>i)) continue;
    			if(!p[i]){p[i]=x; pos++; break;}
    			else x^=p[i]; 
    		} return ;
    	}
    	inline void solve()
    	{
    		ul res=0;
    		for(int i=1;i<=n;++i) a[i]=read();
        	for(int i=0;i<=32;i++)
        	{
        		for(int j=0;j<=32;j++)
        		{
    		 		int fg1=0,fg2=0,fg3=0;
    		 		for(int k=1;k<=n;k++)
    		 		{
    		  		   	if(a[k]>>i&1)fg1=1;
    		 		   	if(a[k]>>j&1)fg2=1;
    		    	    if((a[k]>>i&1)!=(a[k]>>j&1))fg3=1;
    		     	   	if(fg1&&fg2&&fg3)break;
    		    	}
    		    	if(!fg1||!fg2)continue;
    		    	if(i+j-fg3-1<0)res++;
    		    	else ans+=1ull<<(i+j-fg3-1);
        		}
        	}
        	ans+=res>>1; res&=1; 
       		printf("%llu",ans);
        	if(res)printf(".5
    ");
        	else puts("");
        	return ;
    	}
    	signed main()
    	{
    		n=read(); m=read();
    		if(m==1)
    		{
    			ul res=0;
    			for(int i=1;i<=n;++i) res|=read();
    			if(res%2==0) printf("%llu
    ",res/2);
    			else printf("%llu.5
    ",res/2);
    			return 0; 	
    		}
    		if(m==2) solve();
    		if(m>=3)
    		{
    			for(int i=1;i<=n;++i) a[i]=read();
    			if(m==3) siz=22; else if(m==4) siz=15; else siz=12;
    			for(int i=1;i<=n;++i) insert(a[i]);
    			for(int i=0;i<=siz;++i) if(p[i]) a[cnt++]=p[i]; s=1<<pos;
    			for(int i=0;i<s;++i)
    			{
    				int x=0;
    				for(int j=0;j<cnt;++j) 
    				{
    					if((i>>j)&1) x^=a[j]; 
    				} 
    				int r1=0,r2=1;
    				for(int j=1;j<=m;++j)
    				{
    					r2*=x; r1*=x; r1+=r2>>pos; r2&=s-1;
    				}
    				ans+=r1; las+=r2; ans+=las>>pos; las&=s-1; 
    			} 
    			printf("%lld",ans); if(las) puts(".5"); else puts("");
    		}
    		return 0;
    	}
    }
    signed main(){return yspm::main();}
    
    ``
  • 相关阅读:
    LeetCode 1275. 找出井字棋的获胜者 Find Winner on a Tic Tac Toe Game
    LeetCode 307. 区域和检索
    LeetCode 1271 十六进制魔术数字 Hexspeak
    秋实大哥与花 线段树模板
    AcWing 835. Trie字符串统计
    Leetcode 216. 组合总和 III
    Mybatis 示例之 复杂(complex)属性(property)
    Mybatis 示例之 复杂(complex)属性(property)
    Mybatis 高级结果映射 ResultMap Association Collection
    Mybatis 高级结果映射 ResultMap Association Collection
  • 原文地址:https://www.cnblogs.com/yspm/p/13394913.html
Copyright © 2011-2022 走看看