【bzoj 3687 簡單題】【bitset的dp揹包優化】【bitset的妙用】
阿新 • • 發佈:2018-12-13
【題意】
求n個數的所有子集的和的異或值
【分析】
要求計運算元集算術和的異或和。首先我們設dp[i]表示由這n個數能有多少種方案組成i,顯然這樣dp[1~sum]就將所有的子集和統計完了,那麼計算的時候只要判斷(dp[i]&1)就有ans^=i。這樣的複雜度是sum*n,對於n=10^3,sum=2*10^6是處理不了的。那我們回過頭看看這個dp決策,假設前i個數組成的是dp',那麼在加入第i+1個數的時候每一個dp[j]+=dp[j-a[i+1]]]。而且我們可以將dp換成只有0/1,那麼dp[j]=(dp[j]+dp[j-a[i+1]])%2。即dp''=dp'^(dp'<<a[i+1])==>ans^=ans<<a[i+1],用bitset就行了。
【程式碼】
#include<bits/stdc++.h> using namespace std; const int maxn = 1e5 + 6; int a[maxn]; bitset<maxn>b; int main() { int n; scanf("%d", &n); int sum = 0; b[0] = 1; for (int i = 1; i <= n; i++) { int x; scanf("%d", &x); sum += x; b ^= b << x; } int ans = 0; for (int i = 1; i <= sum; i++) { if (b[i])ans++; } printf("%d\n", ans); }