列表

详情


NC21620. 牛牛xor牛妹

描述

牛牛有一个集合{1,2,...,N}

牛妹有一个集合{1,2,...,M}

牛牛要从自己的集合里面选出一个子集,牛妹也一样

要求两个人选出的子集交集为空并且牛牛的子集的xor和小于牛妹的子集的xor和

求他们一共可以选择多少不同对的子集,模1e9+7

输入描述

输入一行包含两个整数n,m (1<=n,m<=2000)

输出描述

输出一个整数

示例1

输入:

2 2

输出:

4

示例2

输入:

47 74

输出:

962557390

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 389ms, 内存消耗: 620K, 提交时间: 2020-06-25 16:58:41

#include<bits/stdc++.h>
using namespace std;

const int N = 2048;
const int mod = 1e9 + 7;

int dp[2][N][2];

void add(int &a, int b){
	a += b;
	if(a >= mod)	a -= mod;
}

int main(){
	int n, m;
	scanf("%d %d", &n, &m);
	int l = max(n, m);
	
	int ans = 0;

	for(int P=11; P>=0; P--){
		memset(dp, 0, sizeof(dp));
		dp[0][0][0] = 1;

		for(int i=1; i<=l; i++){
			for(int j=0; j<N; j++){
				dp[1][j][0] = dp[0][j][0];
				dp[1][j][1] = dp[0][j][1];
			}

			for(int j=0; j<N; j++){
				if(i <= n){
					add(dp[1][j^i][0], dp[0][j][0]);
					add(dp[1][j^i][1], dp[0][j][1]);
				}
				if(i <= m){
					if(i >> P & 1){
						add(dp[1][j^i][1], dp[0][j][0]);
						add(dp[1][j^i][0], dp[0][j][1]);
					} else {
						add(dp[1][j^i][0], dp[0][j][0]);
						add(dp[1][j^i][1], dp[0][j][1]);
					}
				}
			}

			swap(dp[0], dp[1]);
		}

		for(int i=0; i<N; i++){
			if((i >> P) == 1){
				add(ans, dp[0][i][1]);
			}
		}
	}

	printf("%d\n", ans);
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 481ms, 内存消耗: 504K, 提交时间: 2019-12-11 19:47:05

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int p=1e9+7;
int nt,pr,mx,ans,n,m,i,j,x,op,l,k,hh,ha,f[2][2048][2][2];
int main(){
	scanf("%d%d",&n,&m);
	hh=max(n,m);
	for(op=0;;op++){
		if((1<<op)>hh)break;
		mx=hh>>op;
		for(j=0;j<=min(2047,mx*2);j++)
			 for(l=0;l<2;l++)
			  for(k=0;k<2;k++)f[0][j][l][k]=0;
		f[0][0][0][0]=1;
		for(i=1;i<=hh;i++){
			nt=i&1;pr=nt^1;
			for(j=0;j<=min(2047,mx*2);j++)
			 for(l=0;l<2;l++)
			  for(k=0;k<2;k++)f[nt][j][l][k]=0;
			x=i>>op;ha=x&1;
		 for(j=0;j<=min(2047,mx*2);j++)
		  for(l=0;l<2;l++)
		   for(k=0;k<2;k++){
		   	(f[nt][j][l][k]+=f[pr][j][l][k])%=p;
			if(i<=m)(f[nt][j^x][l][k^ha]+=f[pr][j][l][k])%=p;
			if(i<=n)(f[nt][j^x][l^ha][k]+=f[pr][j][l][k])%=p;
		   }
		}
		ans=(ans+f[nt][1][0][1])%p;
		//printf("%d %d\n",nt,ans);
	}
	printf("%d",ans);
}

上一题