Moamen and XOR(dp+组合数)
Moamen and XOR
https://codeforces.com/problemset/problem/1557/C
题意:
建了一个由n个非负整数组成的数组,其中每个元素都小于2k。如果a1&a2&a3&……&an,≥a1⊕a2⊕a3⊕…⊕an.表示Moamen获胜,&表示按位AND运算,以及⊕ 表示按位异或运算。请计算Moamen阵列a的获胜次数。由于结果可能非常大,请打印模100000007(109+7)的值。
思路:dp+组合数

代码:
#include <bits/stdc++.h>
using namespace std;
#define N 200010
int pw[N],f[N][2];//f[i][0]表示n个数从k-1位到i位ans=xor, f[i][1]表示n个数从k-1位到i位ans>xor,
const int mod=1000000007;
int main(){
int t,n,k,i;
pw[0] = 1;
for(i = 1;i < N;i++)pw[i] = pw[i-1] * 2LL % mod;//预处理2的阶乘
scanf("%d",&t);
while(t--){
scanf("%d %d",&n, &k);
memset(f, 0, sizeof(f));
f[k][0] = 1;
if(n&1){//n为奇数
for(i = k - 1;i >= 0;i--){
f[i][1] = (1LL * f[i + 1][1] * pw[n]) % mod;//n个数第i位随便选1
f[i][0] = (1LL * f[i + 1][0] * (pw[n - 1]+1)) % mod;
}
}
else{
for(i = k - 1;i >= 0;i--){
f[i][1] = (1LL * f[i + 1][1] * pw[n] + 1LL * f[i + 1][0] % mod) % mod;
f[i][0] = (1LL * f[i + 1][0] * (pw[n - 1] - 1)) % mod;
}
}
printf("%d\n",(f[0][0] + f[0][1]) % mod);//输出and>=xor
}
return 0;
}

浙公网安备 33010602011771号