引
题目第一句才有用
解法
注意题目中
%
2
\%2
%2就是判断奇偶性,而且2是个小质数
考虑用卢卡斯定理,
C
m
n
=
C
m
/
2
n
/
2
∗
C
m
%
2
n
%
2
C_{m}^{n}=C_{m/2}^{n/2}*C_{m\%2}^{n\%2}
Cmn=Cm/2n/2∗Cm%2n%2
联想到二进制拆分,比如:
C
5
3
=
C
1
0
∗
C
0
1
∗
C
1
1
=
0
,
3
=
01
1
(
2
)
,
5
=
10
1
(
2
)
C_{5}^{3}=C_{1}^{0}*C_{0}^{1}*C_{1}^{1}=0,3=011_{(2)},5=101_{(2)}
C53=C10∗C01∗C11=0,3=011(2),5=101(2)
然后
C
1
1
,
C
1
0
,
C
0
1
,
C
0
0
C_{1}^{1},C_{1}^{0},C_{0}^{1},C_{0}^{0}
C11,C10,C01,C00中仅有
C
0
1
=
0
C_{0}^{1}=0
C01=0
可以映射到子集的关系上,按题目的描述说的话就是:
a
b
2
a_{b_{2}}
ab2在
a
b
1
a_{b_1}
ab1的子集中,
a
b
3
a_{b_{3}}
ab3在
a
b
2
a_{b_{2}}
ab2的子集中
.
.
.
.
.
.
......
......
然后枚举子集即可,是
O
(
3
log
max
{
a
i
}
)
O(3^{\log \max\{a_i\}})
O(3logmax{ai})
#include <iostream>
const int mod = 1e9 + 7,N=250005,inf=0x3f3f3f3f;
using namespace std;
int f[N];
int main(){
int n,a,ans=0;scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%d",&a);
for(int S=a-1&a;S;S=S-1&a)(f[S]+=f[a]+1)%=mod;
(ans+=f[a])%=mod;
}
printf("%d\n",ans);
}
完