「CTSC2017」吉夫特【Lucas 定理】【状压DP】
作者:互联网
solution
由\(Lucas\)定理:
\[\binom xy\equiv\binom{x\%2}{y\%2}\binom{x/2}{y/2}\pmod 2 \]也就相当于设\(x_i,y_i\)分别是\(x,y\)二进制下的第\(i\)位
那么:
\[\binom xy\equiv\prod_{i}\binom{x_i}{y_i}\pmod 2 \]因为\(x_i,y_i\in{{0,1}}\),所以只有\(\binom{x_i}{y_i}\)的取值中只有\(\binom 01\)是等于\(0\)的,故
\[\binom {a_{b_{i-1}}}{a_{b_i}}\not =0 \]意味着二进制下\(a_{b_i}\)的每一位都\(\le a_{b_{i-1}}\),将\(a_i\)看作是二进制下每一个\(1\)组成的集合,那么\(a_{b_i}\)必须是\(a_{b_{i-1}}\)的子集,因此我们直接设\(dp_i\)表示以\(i\)结尾的长度超过\(1\)的符合条件的子序列的个数,然后枚举\(i\)的子集转移即可:
code
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
const int N=(1<<20)+10;
int n,a[N],f[N],ans;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
for(int s=(a[i]-1)&a[i];s;s=(s-1)&a[i])
f[s]=(f[s]+f[a[i]]+1)%mod;
ans=(ans+f[a[i]])%mod;
}
cout<<ans;
return 0;
}
标签:const,Lucas,二进制,状压,int,xy,夫特,binom,equiv 来源: https://www.cnblogs.com/tqxboomzero/p/14218494.html