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+组合数

image

代码:

#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;
}

posted @ 2021-08-13 10:49  Curry_BP  阅读(96)  评论(0)    收藏  举报