洛谷 P3773 [CTSC2017]吉夫特

Description

洛谷传送门

Solution

一道卢卡斯定理的变形。

先来看卢卡斯定理:

\[C_n^m mod\ P = C_{n\ mod\ P}^{m\ mod\ P} * C_{n / P}^{m / P} mod\ P \]

在来看这道题目,题目要求我们最后的积为奇数,我们可以对于 \(n\)\(m\) 的每一个二进制位进行考虑。

当且仅当,\(n = 0\)\(m = 1\) 时,\(C_n^m = 0\),此时积为 0,不合法。

所以我们只需要保证 \(m \subseteq n\)

此时,题目就变成了取出一个子序列,使得 \(a_{i - 1} \subseteq a_i\)

所以我们开个桶记录一下输入的每个数出现的位置,枚举每一个数,然后枚举它的二级制下的子集,判断这个子集出现的位置是否在这个数后面(题目要求不上升),如果是的话转移。

Code

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 3e5 + 10;
const int mod = 1e9 + 7;
int n, ans;
int a[N], vis[N], f[N];

int main(){
	scanf("%d", &n);
	for(int i = 1; i <= n; i++)
		scanf("%d", &a[i]), vis[a[i]] = i;
	for(int i = n; i >= 1; i--)
		for(int j = a[i] & (a[i] - 1); j; j = a[i] & (j - 1))
			if(vis[j] > i) f[i] = (f[i] + f[vis[j]] + 1) % mod;
	for(int i = 1; i <= n; i++)
		ans = (ans + f[i]) % mod;
	printf("%d\n", ans);
	return 0;
}

End

posted @ 2021-10-10 21:39  xixike  阅读(50)  评论(0编辑  收藏  举报