题解
考虑 (nchoose m) 什么时候是奇数。
拆开得 ({nchoose m}=frac{n!}{m!(n-m)!}),设 (f(x)=sumlimits_{ige 1}frac{n!}{2^i})。那么显然仅有 (f(n)=f(m)+f(n-m)) 时 ({nchoose m}equiv 1pmod 2)。设 (g(n)=n=g(n/2)+n/2+nmod 2=f(n)+popcount(n))。于是有 (f(n)=popcount(n)-n)。也就是说要满足 (popcount(n)=popcount(m)+popcount(n-m))。其中 (popcount) 代表二进制下有多少个 (1)。
而 (popcount(m)+popcount(n-m)ge popcount(n)) 当且仅当在 (m& n=m) 时才取等。
那么直接dp,然后子集枚举即可。
代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000000;
const int mod = 1000000007;
int n, a[MAXN], pos[MAXN], f[MAXN];
int ans;
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", a + i), pos[a[i]] = i;
for (int i = n; i >= 1; i--) {
f[i] = 1;
for (int j = a[i] & (a[i] - 1); j; j = (j - 1) & a[i]) {
f[i] = (f[i] + f[pos[j]]) % mod;
}
ans = (ans + f[i] - 1) % mod;
}
printf("%d
", ans);
return 0;
}