[BZOJ3811]玛里苟斯
題目
傳送門 to usOJ
題目概要
對于可重集合 SSS ,設其元素個數(shù)為 nnn ,顯然它有 2n2^n2n 個子集。定義集合的權(quán)值為其中元素的異或和,求子集的權(quán)值的 kkk 次方的期望。即:∑s?Sf(s)k2n\frac{\sum_{s\subseteq S}f(s)^k}{2^n}2n∑s?S?f(s)k? 的值,f(s)f(s)f(s) 是集合內(nèi)元素的異或和。
數(shù)據(jù)范圍與約定
n≤105,k≤5n\le 10^5,k\le 5n≤105,k≤5 。
思路
FBLWARNING:我將試著使用奇怪的文風去論述這個問題。\bf{FBL\;\;WARNING}:我將試著使用奇怪的文風去論述這個問題。FBLWARNING:我將試著使用奇怪的文風去論述這個問題。
剛看一眼,就被這道題給嚇住了,nnn 很大,kkk 卻小的可憐,555 站在 10510^5105 旁邊,顯得毫不起眼。但我們不著眼于出題人的區(qū)別對待,我們要拯救每一個 kkk ,讓世界重新充滿愛。
- k=1k=1k=1 的時候,這道題變得平淡無奇,味同嚼蠟。所有的 fff 中,有一半都滿足第 iii 位是一個 111 ,只要 SSS 中存在一個數(shù)字可以提供這個 111 。這是因為,這個數(shù)字是否出現(xiàn),這件事不影響別人,它只負責自己的選擇,就像 zxyzxyzxy 默默的 AKAKAK 。若夫它看到是 000 ,它便義無反顧地將自己融入整個群體;至若此值已經(jīng)為 111 ,它不會出現(xiàn)在人們的視野中,好像從未出現(xiàn)過,又好像一直都在。
- k=2k=2k=2 的時候,我們要做的是一個平方的選擇。兩個元素,雖然不在一個括號中,但是二人的心卻在一起,這就是平方的真諦。二者何人?枚舉則知。不是所有人都能夠相遇,就像人生總會有很多遺憾。如果二者可以被獨立抉擇——存在一個數(shù)字,在第 iii 位為 111 而第 jjj 位為 000 ——那么二人是不容易遇到的,只有 12×12=14\frac{1}{2}\times\frac{1}{2}=\frac{1}{4}21?×21?=41? 。如果不是獨立抉擇,就會翻倍,得到 12\frac{1}{2}21? 了。
- k≥3k\ge 3k≥3 的時候,我們終于可以大展拳腳了。我們有很多方法。我們可以利用答案小于 2632^{63}263 的特點,直接猜到 a≤222a\le 2^{22}a≤222 次方,求出線性基,然后暴力枚舉。我們也可以繼續(xù)學習 k=2k=2k=2 的方案。
我改悔了。
對于 k=2k=2k=2 ,我們拆位,將一個數(shù)字拆成很多個 222 的冪之和。然后平方就是選兩個二進制位唄。
假設最大的一個二進制位是 2x2^x2x ,那么至少有一半的異或和不小于 2x2^x2x ,與 k=1k=1k=1 的情況類似。
所以答案至少有 12?(2x)k<263\frac{1}{2}\cdot(2^x)^k<2^{63}21??(2x)k<263 ,可以解出 x<64kx<\frac{64}{k}x<k64? ,然后就沒了。
作乘法可能會爆 unsignedlonglongunsigned\;long\;longunsignedlonglong ,稍微打的騷一點就好了。
代碼
// 湘妹兒,永遠滴神! #include <cstdio> #include <iostream> #include <vector> using namespace std; typedef unsigned long long int_; int_ readint(){int_ x; scanf("%llu",&x);return x; // cin就能兼容了[滑稽] }int_ d[100]; void insert(int_ x){for(int i=63; i>=0&&x; --i)if(x>>i&1){if(d[i] == 0)d[i] = x;x ^= d[i];} }int n, k, cnt; // 分母是pow(2,cnt) int_ zheng, xiao; // 整數(shù)與小數(shù) void dfs(int t,int_ now){if(t == -1){int_ res = 1; // 加入res*nowfor(int i=1; i<k; ++i)res *= now;int_ yu = res%(1<<cnt);res = res/(1<<cnt);// 變成了res*(1<<cnt)+yuzheng += res*now;xiao += yu*now;zheng += xiao/(1<<cnt);xiao = xiao%(1<<cnt);return ;}if(d[t]) dfs(t-1,now);dfs(t-1,now^d[t]); } int main(){n = readint(), k = readint();for(int i=0; i<n; ++i)insert(readint());int_ all = 0;for(int i=63; i>=0; --i)all |= d[i];if(k == 1){cnt = 1;zheng = all>>1;xiao = all&1;}if(k == 2){cnt = 2;for(int i=32; i>=0; --i)if(all>>i&1)for(int j=32; j>=0; --j)if(all>>j&1){bool apart = false;for(int o=32; o>=0; --o)if((d[o]>>i&1)^(d[o]>>j&1)){ apart = true; break; }int mom = (apart ? 1 : 0)+1;if(i+j >= mom)zheng += (1ull<<(i+j-mom));elsexiao += 1ull<<(i+j+cnt-mom);// 為了讓分母pow(2,mom->cnt)zheng += xiao/(1<<cnt);xiao = xiao%(1<<cnt);}}if(k >= 3){for(int i=0; i<=63; ++i)if(d[i] > 0) ++ cnt;dfs(63,0);}printf("%llu",zheng);if(xiao) putchar('.');while(xiao *= 10){printf("%llu",xiao/(1<<cnt));xiao %= (1<<cnt);}return 0; }總結(jié)
以上是生活随笔為你收集整理的[BZOJ3811]玛里苟斯的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 由于wps没有卸载干净导致office总
- 下一篇: 【面试题】package有什么作用