做这题的前置知识是 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