其他分享
首页 > 其他分享> > [CTSC2017]吉夫特

[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