链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目意思:
求有多少长为 n 的元素是 [0, 2的 m次) 的整数序列
满足存在一个非空子序列的 AND 和是 1
tip:可以在序列中取[1,n]的数 所以需要用到全排列的思想 每次数值取和。
答案对输入的正整数 q 取模 1 ≤ n, m ≤ 5000, 1 ≤ q ≤ 1e9。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 5e3 + 10;
int s[N][N];
int n, m, k, v[N];
int mi(int a, int b){ //快速幂
int cnt = 1;
while(b){
if(b & 1){
cnt *= a;
b --;
cnt %= k;
}
else{
a *= a;
a %= k;
b /= 2;
}
}
return cnt % k;
}
void init(){ //杨辉三角 s[n][i] --> n中取i个数的排列组合。
for(int i = 0; i < N; i ++){
for(int j = 0; j <= i; j ++){
if(j) s[i][j] = (s[i - 1][j] + s[i - 1][j - 1]) % k;
else s[i][j] = 1;
}
}
}
signed main(){
cin >> n >> m >> k;
init();
int ans = 0;
for(int i = 1; i <= n; i ++){ // i奇数个数
int p = 1;
p = mi(2, (n - i) * (m - 1)); //(n - i)指偶数个数 2,(n - i)指每列偶数的情况 除最后一位(必定为1),前 m - 1 位的所以情况;
int l = 1;
l = mi((mi(2, i) - 1) , m - 1) % k; // 同上,多减去1是不用对最后一列进行判断。
ans = (ans + 1 * s[n][i] * l % k * p) % k; // 每次情况的计数。
}
cout << ans << endl;
return 0;
}