2024牛客暑期多校训练营1 A Bit Common

2024牛客暑期多校训练营1   A Bit Common

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

Given two integers nnn and mmm, among all the sequences containing n non-negative integers less than 2^{m}, you need to count the number of such sequences A that there exists a non-empty subsequence of A in which the bitwise AND of the integers is 1.

Note that a non-empty subsequence of a sequence A is a non-empty sequence that can be obtained by deleting zero or more elements from A and arranging the remaining elements in their original order.

Since the answer may be very large, output it modulo a positive integer q.

The bitwise AND of non-negative integers A and B, A  AND B is defined as follows:

  • When A  AND B is written in base two, the digit in the 2^{d}'s place (d≥0) is 1 if those of A and B are both 1  and 0 otherwise.

For example, we have 4 AND 6 = 4 (in base two: 100 AND 110 = 100).

Generally, the bitwise AND of k non-negative integers p1,p2,…,pk​ is defined as
(…((p1 AND p2) AND p3) AND … AND pk)
and we can prove that this value does not depend on the order of p1,p2,…,pk

输入描述:

The only line contains three integers n (1≤n≤5000), m (1≤m≤5000) and q (1≤q≤1e9).

输出描述:

Output a line containing an integer, denoting the answer.

输入

复制
2 3 998244353

输出

复制
17

输入

复制

5000 5000 998244353

输出

复制

2274146

思路

刚开始看到这题,脑子里毫无思路,感觉根本无从下手,后来听老师讲后才有所灵感。

题目求有多少长为 n 的元素是 [0, 2^{m}) 的整数序列,并且满足存在一个非空子序列的 AND 和是 1,答案要取模q防止答案爆long long。

如果一个数的二进制的最低位为1,那么其子序列AND和为1,并且包含这个子序列的子序列的AND和也为1;

对于二进制的最低位为0的数,除了 最低位都可以任选;

公式: \binom{n}{k}2^{(n-k)(m-1)}(2^{k}-1)^{m-1}  对k从1到n求和

其中k代表奇数的个数,(2^{k}-1)^{m-1} 代表奇数的方案数,2^{(n-k)(m-1)}  代表偶数的方案数

 

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,p;
int c[5005][5005];
int mi(int u,int x){
	int res=1;
	while(x){
		if(x&1){
			res*=u;
		}
		u*=u;
		res%=p;
		x>>=1;
		u%=p;
	}
	return res;
}
signed main()
{
	cin>>n>>m>>p;
	
	//用杨辉三角求组合数 
	c[0][0]=1;
	for(int i=1;i<5002;i++){
		c[i][0]=1;
		for(int j=1;j<=i;j++){
			c[i][j]=(c[i-1][j-1]+c[i-1][j])%p;
		}
	}
	int sum=0; 
	for(int i=1;i<=n;i++){
		int aa=mi(2,n-i);
		int a=mi(aa,m-1);
		int b=mi(mi(2,i)-1,m-1);
		int cc=c[n][i];
		int h=a%p*b%p*cc%p;
//		或者
//			int h=mi(2,(n-i)*(m-1))%p*mi(mi(2,i)-1,m-1)%p*c[n][i]%p;
		sum+=h;
		sum%=p;
		
	}
	cout<<sum<<endl;
	return 0;
 } 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值