bzoj 3811 瑪里苟斯

2022-06-02 07:12:08 字數 4279 閱讀 7288

time limit: 10 sec  memory limit: 256 mb

submit: 190  solved: 95

[submit][status][discuss]

魔法之龍瑪里苟斯最近在為加基森拍賣師的削弱而感到傷心,於是他想了一道數學題。

s 是乙個可重集合,s=。

等概率隨機取 s 的乙個子集 a=。

計算出 a 中所有元素異或 x, 求 xk 的期望。

第一行兩個正整數 n, k。

以下 n 行每行乙個整數,表示 ai。

如果結果是整數,直接輸出。如果結果是小數(顯然這個小數是有限的),輸出精確值(末尾不加多餘的 0)。

4 2012

33.5

首先,對於題目的答案小於263,我們可以看出對於不同的k,ai是不同的:

k=1,ai

<263

k=2,ai

<232

k=3,ai

<221

k=4,ai

<216

k=5,ai

<213

首先,因此我們依據資料範圍,對於不同的ai有不同的解法。

其次,題目要求輸出精確的小數,由以下推導我們可以知道,小數最多只有.5,不可能存在.25,.125這樣的:

對於求出來了其中一種情況x,他對答案的貢獻是xk*p,其中p是該情況出現的概率。

我們以x=2為例,其他k的情況類似:

我們把這個x按二進位制分成了最多n位,也就是最大的數的最高位為n。那麼他的k次方是(w0*20+w1*21+w2*22……+wn*2n)*(w0*20+w1*21+w2*22……+wn*2n),展開就是w0*w0*20*20+w0*w1*20*21……wn*wn*2n*2n。其中wi是它每個二進位制位的值。

對於每個項wi*wj*2i+j,他存在的情況是wi為1且wj為1,也就是該位異或和為1。那麼他的存在的概率為p/2n(n為輸入的數列數字數),p為該兩位皆為1的情況數。

證明題外話:對於數列,我們可以先做個線性基,把線性相關的數字去掉,剩下的都是線性無關的數,這樣方便處理。

我們可以構造乙個異或(%2)的增廣矩陣來求解這樣的乙個p的數量,x1~xn,即xi代表這個數字是否在集合中,作為乙個行向量x,把所有數字按按二進位制位分解,每個數字佔一列,構造乙個矩陣mart.

那麼我們求解的是x*mart=ans,ans為乙個行向量,只有你要求的對應位為1,其餘為0。

假如我們求解的是i位和j位,我們的矩陣對應方程差不多是這樣的:

(2333 此處^為異或)

x1*w(1,0)^x2*w(2,0)^x3*w(3,0) ……^xn*w(n,0) =0;

x1*w(1,1)^x2*w(2,1)^x3*w(3,1) ……^xn*w(n,1) =0;

……x1*w(1,i)^x2*w(2,i)^x3*w(3,i) ……^xn*w(n,i) =1;

……x1*w(1,j)^x2*w(2,j)^x3*w(3,j) ……^xn*w(n,j) =1;

……x1*w(1,n)^x2*w(2,n)^x3*w(3,n) ……^xn*w(n,n) =0;

下面還有n-n個方程,對應更高位。畢竟是個矩陣嘛行數等於列數,但它們的w全為0,等號右邊也為0,對求解無影響就不列舉了。

其中w(i,j),j代表數列第i個數字的第j位。

我們經過高斯消元以後弄成上三角,可以得出有t個f[i][i]非零的行,那麼只有這t個xi是有唯一解的,其他的xi有多解。因為%2,所以其他xi有2解,那麼總共就有2n-t個解,即p=2n-t;

那麼wi*wj存在的概率為p/2n=1/(2t);

那麼每項對答案的貢獻為2i+j-t。

對於i≠j,i+j≥1,t≤2,因此最多小數點後1位.5。

對於i==j,上述方程只有一行初始為1,所以t≤1,i+j≥0,也是最多.5。

上述結論擴充套件成k=n的情況,無非是方程等於1的行增加為n。

如果我們求解的位(wi*wj*wt.....)中有k位不同,那麼方程等於1的行就縮小為k行,因此i+j+t....≥0+1+……k-1=k*(k-1)/2>=k-1=t-1,k≥2。

∴σp-t>=-1,p為所求解對應位的位號。對應k=2的貢獻2i+j-t,k=n貢獻為2σp-t>=2-1。所以最多有一位小數.5。

k=1顯而易見最多/2所以k=1也是最多也是.5。

至此證明完畢。

接下來我們對應資料範圍,提出三種不同範圍下的解法:

k=1時,就求x的期望,它是線性的。對於所有數的所有子集的異或和,我們從他們某個二進位制位看。如果有數字該位為1,那麼該位有奇數個1和偶數個1的概率是相等的,皆為1/2。為奇數個為該位為1的情況,為1/2。如果沒有則不可能為1,該位始終為0。

那麼我們只要把每個數字或一下,然後乘1/2就是答案了。

k≥3時,由於ai

<221 ,即使列舉0~ai也最多百萬級別的時間複雜度。我們可以類似線性基求第k小列舉出所有可能出現的數字。於是我們可以考慮做完線性基後,唯一化,構造新陣列存不為0的元素中。

然後列舉每個數是否加入異或貢獻中,這樣可以求出所有數異或的所有值了。借用之前題目的結論,每個不同的異或值有p=2n-|μ|選擇元素的方法,n為原本陣列個數,|μ|為新構造的陣列個數。那麼每個值出現的概率就是p/總選擇方法數=p/(2n)=1/(2|μ|)的概率,值 乘 概率即為對答案的貢獻。

這裡需要做個兩位的高精來保證數字不出現錯誤。

1 #include2

#define clr(x) memset(x,0,sizeof(x))

3#define clr_1(x) memset(x,-1,sizeof(x))

4#define ll unsigned long long

5#define mod 1000000007

6using

namespace

std;

7const

int n=2e5+10

;8 ll a[n],liner[100],per[100];9

bool f[40][40

];10

bool bits[40

];11

intn,m,k,cnt;

12ll ans,res,keepbit;

13void calc(int

bit)

1430}31

}32}33

for(int i=bit;i>=0;i--)

3438 cnt=0;39

for(int i=bit;i>=0;i--)

40if

(liner[i])

41 per[++cnt]=liner[i];

42return;43

}44void solve1(int

n)45

54void solve2(int

n)55

67 bits[i]=zero;68}

69int

p;70

for(int i=32;i>=0;i--)

71for(int j=32;j>=0;j--)

72if(bits[i]>0 && bits[j]>0)73

81if(i+j-p>=0

)82 ans+=(1ll<

83else

8487 ans+=res>>1

;88 res&=1;89

}90return;91

}9293void dfs(int

pos,ll num)

94107 ans+=u;

108 res+=v;

109 ans+=res>>cnt;

110 res&=keepbit;

111return

;112

}113 dfs(pos+1,num^per[pos]);

114 dfs(pos+1

,num);

115return

;116

}117

void solve3(int n,int

k)118

125int

main()

126137

else

138142 printf("

%llu

",ans);

143if(res) printf(".5"

);144 printf("\n"

);145

return0;

146 }

view code

BZOJ3811瑪里苟斯

從乙個序列裡面選擇一些數異或起來,求所有異或方案的答案的 k 次方的期望值 n le 100000,1 le k le 5 對於 k 1 的情況,對於每一位分開考慮 如果至少有乙個數的當前位是 1 的,那麼有一半的可能性為 0 也就是如果乙個異或方案為 0 那麼選擇其補就能能得到為 1 的結果 使用...

BZOJ 3811 瑪里苟斯(線性基)

description 魔法之龍瑪里苟斯最近在為加基森拍賣師的削弱而感到傷心,於是他想了一道數學題。s 是乙個可重集合,s 等概率隨機取 s 的乙個子集a 計算出 a 中所有元素異或 x,求xk 的期望。input 第一行兩個正整數n,k 以下n 行每行乙個整數,表示ai 1 n 100000,1 ...

bzoj3811 瑪里苟斯 線性基

description 魔法之龍瑪里苟斯最近在為加基森拍賣師的削弱而感到傷心,於是他想了一道數學題。s 是乙個可重集合,s 等概率隨機取 s 的乙個子集 a 計算出 a 中所有元素異或 x,求 x k 的期望。input 第一行兩個正整數 n,k。以下 n 行每行乙個整數,表示 ai。output ...