[CTSC2017]吉夫特

题目传送门

题目第一句才有用

解法

注意题目中 % 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/2Cm%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=C10C01C11=03=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);
}

TXL

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值