2024牛客暑期多校训练营1 A Bit Common
链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
Given two integers nnn and mmm, among all the sequences containing n non-negative integers less than , 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 '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, ) 的整数序列,并且满足存在一个非空子序列的 AND 和是 1,答案要取模q防止答案爆long long。
如果一个数的二进制的最低位为1,那么其子序列AND和为1,并且包含这个子序列的子序列的AND和也为1;
对于二进制的最低位为0的数,除了 最低位都可以任选;
公式: 对k从1到n求和
其中k代表奇数的个数, 代表奇数的方案数, 代表偶数的方案数
#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;
}