Rainbow的信号
Rainbow的信号-AcWing
简洁题意:
给定一个数列,从中等概率的选取区间\([l,r]~(l>r就交换l,r)\),分别求\(and\)和的期望,\(or\)和的期望,\(xor\)和的期望。
solution:
首先,因为位运算只同每一个二进制位有关系,那么我们可以把每一位分开考虑,求和即可(根据数据范围,最多31位)。
当\(l=r\)时出现的概率:\(\frac{1}{n^2}\)
当\(l\neq r\)时出现的概率:\(\frac{2}{n^2}\)(因为当\(l<r\)时,交换\(l,r\))。
设当前考虑第\(i\)位,第\(j\)个数,\(last_0\)表示\(1到j-1\)中最后一个第\(i\)位为\(0\)的数的下标,\(last_1\)表示\(1到j-1\)中最后一个第\(i\)位为\(1\)的数的下标,\(x_0\)表示\(1到j-1\)中第\(i\)位有偶数个\(1\)的以\(j-1\)结尾的区间数量,\(x_1\)表示\(1到j-1\)中第\(i\)位有奇数个\(1\)的以\(j-1\)结尾的区间数量。
目前统计第\(i\)位中,以第\(j\)的数结尾的所有区间,则\(l=[1,j]~,~r=j\)。
\(and\)和:(\(and\)为1要求\(l-r\)中所有的第\(i\)为都为一)
①,此时考虑到的位上为1:
\(+\frac{1}{n^2}2^i\)(当\(l=r\)时,此时必定为1)。
\(+\frac{2}{n^2}2^i(j-last_0-1)\)。(注意排除掉\(l=r\)的情况)。
②,此时考虑到的位上为0:
不进行任何修改。
\(or\)和:(\(or\)为1要求\(l-r\)中至少有一个数第\(i\)位为1)
①,此时考虑到的位上为1:
\(+\frac{1}{n^2}2^i\)(当\(l=r\)时,此时必定为1)。
\(+\frac{2}{n^2}2^i(j-1)\)。(而此时第\(r\)个数的第\(i\)位就是1,所以都可以。注意排除掉\(l=r\)的情况)。
②,此时考虑到的位上为0:
\(+\frac{2}{n^2}2^i\cdot last_1\)(当\(l=[1,last_1]\)时都至少有一个1)。
\(xor\)和:(\(xor\)和要求\(l-r\)中有奇数个第\(i\)位为1)
①,此时考虑到的位上为1:
\(+\frac{1}{n^2}2^i\)(当\(l=r\)时,此时必定为1)。
\(+\frac{2}{n^2}2^i\cdot x_0\)(因为此时第\(i\)位为1,那么之前偶数个为\(1\)的现在就是奇数个了)
②,此时考虑到的位上为0:
\(+\frac{2}{n^2}2^i\cdot x_1\)
更改\(x_0,x_1\):
①,此时考虑到的位上为1:
先交换\(x_0,x_1\),再将\(x_1+1\)(加上\(l=r=j\)的情况)。
②,此时考虑到的位上为0:
再将\(x_0+1\)(加上\(l=r=j\)的情况)。
代码:
#include<bits/stdc++.h>
#define ld long double
using namespace std;
const int N=1e5+5;
ld ans_and,ans_or,ans_xor; 
int n;
int a[N]; 
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	
	for(int i=0;i<31;i++){
		int last0=0,last1=0,x0=0,x1=0;
		ld cnt=(ld)(1<<i); 
		for(int j=1;j<=n;j++){
			int tmp=((a[j]>>i)&1);
			if(tmp){
				ans_and+=cnt*1.0/n/n*1.0;
				ans_and+=cnt*2.0/n/n*1.0*(j-last0-1);
				ans_or+=cnt*1.0/n/n*1.0;
				ans_or+=cnt*2.0/n/n*1.0*(j-1);
				ans_xor+=cnt*1.0/n/n;
				ans_xor+=cnt*2.0/n/n*1.0*x0;
				last1=j;
				swap(x0,x1);
				x1++;			
			}
			else{
				ans_or+=cnt*2.0/n/n*1.0*last1;
				ans_xor+=cnt*2.0/n/n*1.0*x1;
				last0=j;
				x0++;
			}
		}
	}
	
	printf("%.3Lf %.3Lf %.3Lf",ans_xor,ans_and,ans_or); 
	
	return 0;
}
                    
                
                
            
        
浙公网安备 33010602011771号