[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_n^m=C_{n/2}^{m/2}* C_{n%2}^{m%2} % 2 $
可见 \(C_{n}^m mod\ 2 \not = 0\) 的充要条件是\(n,m\)转为\(2\)进制后\(m\)中包含1的位置是n的子集
为什么?
好好思考一下\(Lucas\)的过程,不就可以看成位运算吗?
一旦有\(m>n\),则整个式子值为0
#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
标签:...,int,b1,b2,夫特,include,CTSC2017,mod 来源: https://www.cnblogs.com/list1/p/10473788.html