• UOJ#36. 【清华集训2014】玛里苟斯 线性基


    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ36.html

    题解

    按照 $k$ 分类讨论:

    k=1 : 我们考虑每一位的贡献。若有至少一个数第 $i$ 位为 $1$ ,则对答案的贡献为 $2^i/2$ 。

    k=2 : 发现每个异或和的平方为 $sum_isum_j2^{i+j}bit_ibit_j$。那么考虑第 $i$ 位和第 $j$ 位的积的期望值。如果所有的数中,第 $i$ 位和第 $j$ 位均相等且非全零,那么参考 k=1 的情况,期望为 1/2;否则,第 $i$ 位为 $1$ 的概率为 1/2,第 $j$ 位为 $1$ 的概率为 1/2,$i×j$ 为 $1$ 的概率为 0.25 。
    $kleq 3$ : 由于答案不超过 $2^{63}$ ,直接把线性基搞出来之后暴力枚举就好了。

    代码

    #include <bits/stdc++.h>
    #define clr(x) memset(x,0,sizeof (x))
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    LL read(){
    	LL x=0,f=0;
    	char ch=getchar();
    	while (!isdigit(ch))
    		f|=ch=='-',ch=getchar();
    	while (isdigit(ch))
    		x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    	return f?-x:x;
    }
    const int N=100005;
    int n,k;
    ULL a[N];
    void init(){
    	static ULL x[64];
    	clr(x);
    	n=read(),k=read();
    	for (int i=1;i<=n;i++){
    		ULL v=read();
    		for (int i=63;~i;i--)
    			if (v>>i&1ULL)
    				if (!x[i]){
    					x[i]=v;
    					break;
    				}
    				else
    					v^=x[i];
    	}
    	n=0;
    	for (int i=63;~i;i--)
    		if (x[i])
    			a[++n]=x[i];
    }
    void Out(ULL x){
    	cout<<x/2;
    	if (x&1LLU)
    		cout<<".5";
    }
    namespace k1{
    	void solve(){
    		ULL ans=0;
    		for (int i=1;i<=n;i++)
    			ans|=a[i];
    		Out(ans);
    	}
    }
    namespace k2{
    	void solve(){
    		ULL ans=0;
    		for (int i=0;i<33;i++)
    			for (int j=0;j<33;j++){
    				int f1=0,f2=0,f=0;
    				for (int t=1;t<=n;t++){
    					f1|=a[t]>>i&1ULL;
    					f2|=a[t]>>j&1ULL;
    					f|=(a[t]>>i&1ULL)!=(a[t]>>j&1ULL);
    				}
    				if (!f1||!f2)
    					continue;
    				ans+=1ULL<<(i+j-f);
    			}
    		Out(ans);
    	}
    }
    namespace k3{
    	__int128 tot;
    	__int128 Pow(__int128 x,int y){
    		__int128 ans=1;
    		for (;y;y>>=1,x*=x)
    			if (y&1)
    				ans*=x;
    		return ans;
    	}
    	void solve(){
    		tot=0;
    		for (int i=(1<<n)-1;i>=0;i--){
    			ULL tmp=0;
    			for (int j=0;j<n;j++)
    				if (i>>j&1)
    					tmp^=a[j+1];
    			tot+=Pow(tmp,k);
    		}
    		while (tot%2==0&&n>1)
    			n--,tot/=2;
    		cout<<(ULL)tot/2;
    		if (tot%2==1)
    			cout<<".5";
    	}
    }
    int main(){
    	init();
    	if (k==1)
    		k1::solve();
    	else if (k==2)
    		k2::solve();
    	else
    		k3::solve();
    	return 0;
    }
    

      

  • 相关阅读:
    nRF5 SDK for Mesh(二) Getting started 快速开始
    QT 简单 TCP 通信,发送数据到服务器
    Bluetooth® Low Energy Beacons
    CC2540 低功耗串口, POWER_SAVING 模式 下 串口 0 的使用
    LWIP network interface 网卡 初始化 以 STM32 为例子 后面会有 用 2G 或者4G 模块 用 PPP拨号的 形式 虚拟出网卡 所以先以 这个为 前提
    R 语言入门
    Django 框架
    Windows 下 Django 安装
    windows 下搭建 git 服务器 copssh+git
    python Pystaller 将python文件打包成exe
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/UOJ36.html
Copyright © 2020-2023  润新知