做这题的前置知识是 Lucas 定理,可以先做一下这题。
我就当大家都会 Lucas 定理了awa。
Lucas 定理:
\[ C^m_n\!\equiv\!C^{\left\lfloor\frac{m}{p}\right\rfloor}_{\left\lfloor\frac{n}{p}\right\rfloor}\times C^{m\mod p}_{n\mod p}\pmod{p} \]
所以我们来看看原式:
\[ \prod_{i=2}^k \dbinom{a_{b_i}}{a_{b_{i-1}}}\!\mod 2 \]
重点就在于 \(\!\mod 2\) 这个地方。
由 Lucas 定理可知,原式的答案不是 0,就是 1。
所以我们要保证 \(\forall \dbinom{a_{b_i}}{a_{b_{i-1}}} \equiv 1 \pmod 2\)。
又因为 \(\dbinom{0}{0}\),\(\dbinom{1}{0}\),\(\dbinom{1}{1}\) 为 1,\(\dbinom{0}{1}\) 为 0。
根据 Lucas 定理,每次 \(\mod 2\) 相当于把 \(a_{b_i}\) 和 \(a_{b_{i-1}}\) 二进制拆分,并且保证,\(a_{b_i}\) 为 0 的那个位上 \(a_{b_{i-1}}\) 不能为 1。
即 \(a_{b_{i}}\!\And a_{b_{i-1}}\!=\!a_{b_i}\),我们设 \(f(i)\) 为以 \(i\) 开头的子序列数,枚举子集进行 dp 即可。
\(p.s.\) 在最后累加的时候,要减去只有一个数的情况。
代码如下:
#include<bits/stdc++.h>
#define rint register int
using namespace std;
inline int read(){
int s=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=0;c=getchar();}
while(c>='0'&&c<='9')s=(s<<1)+(s<<3)+c-48,c=getchar();
return f?s:-s;
}
const int Mod=1e9+7;
int n,a[300010],f[300010],ans;
int main(){
n=read();
for(rint i=1;i<=n;++i) a[i]=read();
for(rint i=n;i;--i){
for(rint j=(a[i]-1)&a[i];j;j=(j-1)&a[i])
f[a[i]]=(f[a[i]]+f[j])%Mod;
f[a[i]]=(f[a[i]]+1)%Mod;
}
for(rint i=1;i<=n;++i) ans=(ans+f[a[i]]-1)%Mod;
printf("%d",ans%Mod);
return 0;
}
没了awa。
来源:https://www.cnblogs.com/LCGUO/p/12468514.html