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}{m/2} ast C_{n ext{%} 2}^{m ext{%} 2} ext{ % } 2 $
可见 (C_{n}^m mod 2 ot = 0) 的充要条件是(n,m)转为(2)进制后(m)中包含1的位置是(n)的子集
为什么?
好好思考一下(Lucas)的过程,不就可以看成位运算吗?
一旦有(m>n),则整个式子值为(0)
故子序列中一个数的后一位(a_j)必须满足 $ a_{i} ext{&} 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
",(ans-n+mod)%mod);
return 0;
}
g