[CTSC2017]吉夫特
Description:
给定一个序列\(a_1,a_2,a_3...a_n\)
求有多少个不上升子序列:
\(a_{b1},a_{b_2}...\) 满足 \(C_{a_{b1}}^{a_{b2}}*C_{a_{b2}}^{a_{b3}}*.....mod\ 2 >0\)
输出对\(10^9+7\)取模的结果
Hint:
$ 1 ≤ n ≤ 211985, 1 ≤ ai ≤ 233333\(。所有的\) a_i $互不相同
Solution:
由\(Lucas\)定理:
$ C_nm=C_{n/2} \ast C_{n \text{%} 2}^{m \text{%} 2}\ \text{ % } \ 2 $
可见 \(C_{n}^m mod\ 2 \not = 0\) 的充要条件是\(n,m\)转为\(2\)进制后\(m\)中包含1的位置是\(n\)的子集
为什么?
好好思考一下\(Lucas\)的过程,不就可以看成位运算吗?
一旦有\(m>n\),则整个式子值为\(0\)
故子序列中一个数的后一位\(a_j\)必须满足 $ a_{i} \text{&} a_{j} = a_{j} $
枚举二进制位1的子集,直接\(dp\)就行
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ls p<<1
#define rs p<<1|1
using namespace std;
typedef long long ll;
const int mxn=1e6+5,mod=1e9+7;
int n,ans,a[mxn],f[mxn],rk[mxn];
inline int read() {
char c=getchar(); int x=0,f=1;
while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
return x*f;
}
inline void chkmax(int &x,int y) {if(x<y) x=y;}
inline void chkmin(int &x,int y) {if(x>y) x=y;}
int main()
{
n=read();
for(int i=1;i<=n;++i) a[i]=read(),rk[a[i]]=i,f[a[i]]=1;
for(int i=1;i<=n;++i)
for(int j=(a[i]-1)&a[i];j;j=(j-1)&a[i])
if(rk[j]>i) f[j]=(f[j]+f[a[i]])%mod;
for(int i=1;i<=n;++i) ans=(ans+f[a[i]])%mod;
printf("%d\n",(ans-n+mod)%mod);
return 0;
}
g