2019牛客暑期多校訓練營(第一場)線性基

2022-07-27 18:12:13 字數 1251 閱讀 9323

題意:給定n個整數,求所有異或和為0的子集的大小和。

思路:看到異或和,差不多就要往線性基上想。如果一些數異或和為0,肯定是線性基里的一些數和線性基外的一些數異或得到的,因為線性基外的數都能由線性基里的數異或得到。

先對n個數求線性基lb,設線性基大小為r。

2.線性基內的數的貢獻:對於每乙個線性基內的數,如果有乙個不包含它的線性基(由除它外的n-1數組成)能把它表示出來,那麼它也就相當於是另乙個線性基外的數,他的貢獻也是 2^(n-r-1)。如果該數不能被剩下n-1個數的線性基表示出來,那麼它不會出現在任何子集裡,它的貢獻為0。

關於線性基的介紹,看了好幾篇部落格,這篇比較詳細。

這類題基本都是一樣的套路:

最大異或和

第 k大異或和 / 異或和是第幾大

求所有異或值的和

ac**:

#include#include

#include

#include

using

namespace

std;

const

int mod = 1e9+7

;typedef

long

long

ll;ll pow(ll a, ll n)

return

res;

}struct lb

ll insert(ll x)

else}}

return x>0

; }

};int

main()

else

lb2.insert(ai);

}if(v1.size()==n)

//線性基外的數的總貢獻

ll ans = 1ll* (n-v1.size())* pow(2, n-v1.size()-1) %mod;

//列舉每個線性基內的數

for(int i=0;i)

//如果v[i]能被線性基組成,他就屬於線性基外的數

if(!tmp.insert(v1[i])) ans = (ans + pow(2, n-v1.size()-1)) %mod;

}printf(

"%lld\n

", ans);

}return0;

}

view code

牛客暑期多校訓練營B Boundary

給定n個點,然後確定乙個過原點的圓,要使這n個點盡可能多的存在與圓上,最後輸出最多的存在於圓上的點的個數 三點確定乙個圓,我們已知這個圓必定經過原點,所以再依次利用三點求圓心的公式列舉每兩個點與原點 三點不共線 確定的圓心,最後選擇確定次數最多的圓心構成的圓 include include incl...

2019牛客暑期多校訓練營(第一場)

題意 題解 c 版本一 題意 題解 c 版本一 題意 題解 c 版本一 題意 題解 c 版本一 題意 題解 c 版本一 題意 題解 數學 計算幾何 邏輯推理 c 版本一 題解 特例 正三角形 取重心 中點 頂點,則期望為 公式 author stzg language c include inclu...

2019牛客暑期多校訓練營(第九場)

d knapsack cryptosystem 折半搜尋,晚上又去看了挑戰程式設計,對於時間複雜度高的情況,可以通過犧牲空間來降低時間複雜度。先把前半部分所有可以組合的情況列舉出來,然後對於後半部分依次列舉,那麼複雜度變化為o 2 36 o 2 18 2 18log 18 顯然就可做了,折半的裸題。...