題意:給定n個整數,求所有異或和為0的子集的大小和。
思路:看到異或和,差不多就要往線性基上想。如果一些數異或和為0,肯定是線性基里的一些數和線性基外的一些數異或得到的,因為線性基外的數都能由線性基里的數異或得到。
先對n個數求線性基lb,設線性基大小為r。
2.線性基內的數的貢獻:對於每乙個線性基內的數,如果有乙個不包含它的線性基(由除它外的n-1數組成)能把它表示出來,那麼它也就相當於是另乙個線性基外的數,他的貢獻也是 2^(n-r-1)。如果該數不能被剩下n-1個數的線性基表示出來,那麼它不會出現在任何子集裡,它的貢獻為0。
關於線性基的介紹,看了好幾篇部落格,這篇比較詳細。
這類題基本都是一樣的套路:
最大異或和ac**:第 k大異或和 / 異或和是第幾大
求所有異或值的和
#include#includeview code#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;
}
牛客暑期多校訓練營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 顯然就可做了,折半的裸題。...