Imagine A is a NxM matrix with two basic properties
1) Each element in the matrix is distinct and lies in the range of 1<=A[i][j]<=(N*M)
2) For any two cells of the matrix, (i1,j1) and (i2,j2), if (i1^j1) > (i2^j2) then A[i1][j1] > A[i2][j2] ,where
1 ≤ i1,i2 ≤ N
1 ≤ j1,j2 ≤ M.
^ is Bitwise XOR
Given N and M , you have to calculatethe total number of matrices of size N x M which have both the properties
mentioned above.
Input format:
First line contains T, the number of test cases. 2*T lines follow with N on the first line and M on the second, representing the number of rows and columns respectively.
Output format:
Output the total number of such matrices of size N x M. Since, this answer can be large, output it modulo 10^9+7
Constraints:
1 ≤ N,M,T ≤ 1000
SAMPLE INPUT
1
2
2
SAMPLE OUTPUT
4
Explanation
The four possible matrices are:
[1 3] | [2 3] | [1 4] | [2 4]
[4 2] | [4 1] | [3 2] | [3 1]
题目意思:现在给你n,m,代表矩阵的大小,如果矩阵中上任何一个坐标异或值大于另一个坐标时,这个位置上的值也大于另一个位置上的值时就符合是条件,并且矩阵上所有的点都是<=n*m的
我们可以知道所有的坐标x,y对称的点它们的异或值是0,那么主对角线上所有坐标异或都是0,根据题意,他们就必须是1~N*M中最小的几个数,比如4*4的矩阵他们就得是1,2,3,4,而与对角线对称的所有坐标异或也肯定是相同的,比如4*4矩阵中的3,4与4,3异或值最大是7,我们把他俩归属为第一梯队,这俩位置上的值只能是15和16,当然他俩可以互换位置,也就是要全排列,那么接下来那些异或值小的坐标就是下一梯队,比如2,4与4,2是13,14两个数。最后一个梯队肯定是主对角线的坐标因为异或值都是0。当然当一个矩阵很大肯定会出现很多个坐标异或值相同,只要异或值相同他们就属于一个梯队,这个梯队内的值就要全排列。最后科普一个知识。
2的次方有:1,,2,4,8,16,32,64,128,256,512,1024。最后一个就是2^10。任何一个数前几项和都是这个数-1,比如:64的前几项和是1+2+4+8+16+32=63。
异或是基于2进制的运算,想一下异或的规则,我上边写的是2的次方换成2进制就是1,10,100,1000.....10000000000。那么我们就知道1000肯定在1024也就是2^10之内的,然后异或值要最大肯定是想要每位全是1,那么1024是10000000000,那么1024-1的异或值就是每位全是1 的值。也可以理解为1+10+100+...+1000000000。那么1000以内异或值肯定1023够了
#include<stdio.h> #include<string.h> #include<math.h> #include<queue> #include<algorithm> #define inf 0x3f3f3f3f #define ll long long #define maxx 5000000 using namespace std; const ll mod=1e9+7; int mapp[1000005]; ll a[1000005]; int main() { int t,n,m; scanf("%d",&t); memset(a,0,sizeof(a)); a[0]=1; for(int i=1;i<=1000000;i++) a[i]=(a[i-1]*i)%mod; while(t--) { memset(mapp,0,sizeof(mapp)); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) mapp[i^j]++; } ll ans=1; for(int i=0;i<=1023;i++) { ans=(ans*a[mapp[i]])%mod; } printf("%lld\n",ans); } }