題目:
蒜頭國有 nn 座城市,編號分別為 0,1,2,3,...,n-1。編號為 x和 y的兩座城市之間如果要修高速公路,必須花費 x|y個金幣,其中|
表示二進位制按位或。
吝嗇的國王想要花最少的**修建高速公路,使得所有城市可以通過若干條高速公路互相達到。現在請你求出 n=2019時,一共有多少不同的方案,
能讓所有城市連通並且造價最低。方案數可能很大,你只需輸出對 10^9+7取模的結果。
樣例輸入
無樣例輸出
無思路:
這一題的主要考點是位運算和最小生成樹。
分析:根據題意我們可以知道這顆樹的邊權值是x|y,而目的是生成乙個最小樹。所以我們要選擇邊權值最小的,在什麼情況下x|y最小的呢? x|y >= x 當且僅當 在二進位制下,x的為0的位置,對應y必須為0,x為1的位置,對應y可以為0也可以為1。
解決完邊權值的問題,下面就是如何生成乙個最小樹?
我們先思考一般情況:此時,我們已經構造出乙個樹,我們需要向其中加入乙個結點,我們如何選擇?當然是選擇和要加入結點邊權值最小的結點相連。而在這一題中,根據上文的論述,我們只需要統計當前結點i在二進位制下有多少1(假設有n個1),因為1的位置我們可以變化,而0的位置 我們不可以變。所以一共有2^n - 1 個可能的選擇。之後我們在用這個樹之前的可能構造數乘(2^n - 1 )就是一般情況下的解決。
之後我們考慮起點的情況:我們發現編號0與任何乙個數進行or運算都是0,所以0可以和任何乙個結點相連都是最小的。那麼,我們就可以選擇0作為我們起點。
**自:
1<1<
i<<1就是把i左移一位,即i乘以2,假如i=5,最後結果就是5*2=10
至於為什麼左移一位是乘以2,這是運算器內部機理,說起來就更多了,計算機做乘法運算的時候不是乙個個的相加,而是用移位來實現的。>>這個符號是右移,與左移相反,右移是除以2.
這裡還有一點容易搞錯的,就是移位符號的左邊是需要計算的數,右邊是需要移動的位數。
**:
#includeusingnamespace
std;
const
int mod = 1e9 + 7
;int
main()
ans = ans * ((1
<< cnt) - 1) % mod;//
(1<}
cout
}
2019 藍橋杯省賽 B 組模擬賽(一)
d.結果填空 馬的管轄 e.填空 lis f.程式設計 找質數 思路 因為時間複雜度的問題,o n n 的時間複雜度可能會超時,可以選擇的篩選素數的方法有埃氏篩法o n logn 尤拉篩法,這裡選的是尤拉篩法o n 直接遍歷找兩個素數相加等於n 因為要求字典樹最小,所以不會超時 ac include...
2019 藍橋杯省賽 B 組模擬賽 程式設計 好友
題目 如下 includeusing namespace std int a 100005 int main 這道題如果你用暴力每次回溯去計算次數,就算加乙個優化,還是不能通過全部資料,因為暴力的複雜度達到了o n 2 這道題要用到二分的思想,首先將所有漁民房子的座標從小到大排序,然後從第乙個開始尋...
2018 藍橋杯省賽 B 組模擬賽(一)
給你乙個序列,請你在其中求出一段最長嚴格上公升的部分,它不一定要連續。include includeusing namespace std int f 10000 b 10000 int lis int n res max res,f i return res 1 int main printf d...