链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
Given two integers nnn and mmm, among all the sequences containing nnn 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 111.
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 qqq.
The bitwise AND of non-negative integers A and B, A AND BA\ \texttt{AND}\ BA AND B is defined as follows:
- When A AND BA\ \texttt{AND}\ BA AND B is written in base two, the digit in the 2^d's place (d≥0d \ge 0d≥0) is 1 if those of A and B are both 1, and 0 otherwise.
For example, we have 4 AND 64\ \texttt{AND}\ 64 AND 6 = 444 (in base two: 100 AND 110100\ \texttt{AND}\ 110100 AND 110 = 100100100).
Generally, the bitwise AND of kkk non-negative integers p1,p2,…,pkp_1, p_2, \ldots, p_kp1,p2,…,pk is defined as
(…((p1 AND p2) AND p3) AND … AND pk)(\ldots((p_1\ \texttt{AND}\ p_2)\ \texttt{AND}\ p_3)\ \texttt{AND}\ \ldots\ \texttt{AND}\ p_k)(…((p1 AND p2) AND p3) AND … AND pk)
and we can prove that this value does not depend on the order of p1,p2,…,pkp_1, p_2, \ldots, p_kp1,p2,…,pk.
输入描述:
The only line contains three integers nnn (1≤n≤5 0001 \le n \le 5\,0001≤n≤5000), mmm (1≤m≤5 0001 \le m \le 5\,0001≤m≤5000) and qqq (1≤q≤1091 \le q \le 10^91≤q≤109).
输出描述:
Output a line containing an integer, denoting the answer.
链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
示例1
输入
2 3 998244353
输出
17
示例2
输入
5000 5000 998244353
输出
2274146
———————————————————————————————————————————
作为一名acm新手,一开始看到这题的时候翻译都给错了(给我的队友道个歉)。后面补题时,过了好久我才慢慢地理解了这串公式的含义。
题目大意:自选一串长度为n数组,每个数字都小于2^m,然后这串数组中有一串子序列中所有的元素AND的值为1。最后输出数组的个数。
对于一组数字全部AND的结果是1,那么我们就可以得知,这些数字的二进制最后一位都为1,也就是都为奇数,这个时候我们就可以通过去枚举数组中的奇数和偶数的个数,即在数组,奇数的个数为1~n中,其所产生的可能的数组全部加起来,即为最终的答案。
首先我们先找奇数的个数:由于K个奇数,在二进制的每一位都有0或1两种可能,所以K个奇数就有2^k个可能,但是所有的组合中,会存在一种K个数在当前位全是1的情况所以,可能的情况就是2^k-1种。这时候一共有m-1个位置,所以先得出了(2^k-1)^(m-1)第一个公式。
其次,我们来看偶数:对于偶数,它们不会对我们的答案产生别的任何影响,只会产生不同的组合,那么我有n-k个偶数,而二进制位数除了最后一位也m-1种。所有就是2^(m-1)^(n-k)。
接着,题目的要求是无序的,即数组中的任何奇数和偶数的位置都是随意的,这时候对于奇数和偶数的排列就是一个组合数。但是由于组合数比较多,所以,我们可以先在外面用
打表的方法(杨辉三角的方式)把组合数先预处理出来。
最后,枚举,将所有的可能
*(2^k-1)^(m-1)*2^(m-1)^(n-k)即为最终答案。
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int c[5005][5005];
int qsm(int x,int y,int p){
int ans=1;
while(y){
if(y%2==1){
ans*=x;
y--;
ans=ans%p;
}
x*=x;
y/=2;
x=x%p;
}
return ans;
}
void initc(int x,int p){
c[0][0]=1;
for(int i=1;i<=x;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;
}
}
}
void solve(){
int n,m,p;
cin>>n>>m>>p;
m--;
initc(5001,p);
int ans=0;
for(int i=1;i<=n;i++){
int x=qsm(2,(n-i)*m,p);
int y=qsm(qsm(2,i,p)-1,m,p);
int z=c[n][i]*x%p*y%p;
ans+=z;
ans=ans%p;
}
cout<<ans<<endl;
}
signed main(){
int t=1;
// cin>>t;
while(t--){
solve();
}
return 0;
}