明明已經廣為流傳, bzoj 就是不貼題面
uoj 題面傳送門吉夫特
考慮 Cmn mod 2≡1 的成立條件
根據 Lucas 定理,有 Cmn mod 2=C⌊m2⌋⌊n2⌋∗Cm mod 2n mod 2
那麼如果這個東西最後等於 0 ,一定存在某一位, m 在這一位上為 1 而 n 為 0
因為 C10 不存在的
那麼就能證明,當n & m = m時 Cmn mod 2≡1
那麼記 f[i] 為以數字 i 結尾的合法方案數
枚舉子集轉移就行了
O(3N) 其中 N 為最大冪次
#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int maxn = 2E5 + 4E4 + 233;const int mo = 1000000007;int n,A[maxn],f[maxn],pos[maxn];#define Add(x,y) ((x) + (y) < mo ? (x) + (y) : (x) + (y) - mo)#define Dec(x,y) ((x) - (y) >= 0 ? (x) - (y) : (x) - (y) + mo)inline int getint(){ char ch = getchar(); int ret = 0; while (ch < '0' || '9' < ch) ch = getchar(); while ('0' <= ch && ch <= '9') ret = ret * 10 + ch - '0',ch = getchar(); return ret;}int main(){ #ifdef DMC freopen("DMC.txt","r",stdin); #endif n = getint(); for (int i = 1; i <= n; i++) A[i] = getint(),pos[A[i]] = i,f[A[i]] = 1; for (int i = 1; i <= n; i++) for (int o = A[i] - 1 & A[i]; o; o = o - 1 & A[i]) if (pos[o] > i) f[o] = Add(f[o],f[A[i]]); int Ans = 0; for (int i = 1; i <= n; i++) Ans = Add(Ans,f[A[i]]); cout << Dec(Ans,n) << endl; return 0;}