SPOJ - VECTAR1 Matrices with XOR property

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章