D - Matrices with XOR property
SPOJ - VECTAR1Imagine 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]
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <map>
using namespace std;
const int maxn = 1030;
const int mod = 1e9+7;
int save[maxn][maxn];
long long A[maxn];
int t;
map<int,int> judge;
vector<pair<int,int> > rigi[maxn];
struct unit{
pair<int,int> ask;
long long res[maxn];
}in[maxn];
int lowbit(int x) {
return x & (-x);
}
void update(int x,int y, int val) {
for(int i = x; i <= maxn; i += lowbit(i)) {
for(int j = y; j <= maxn; j += lowbit(j)) {
save[i][j] += val;
}
}
}
int query(int x, int y) {
int sum = 0;
for(int i = x; i > 0; i -= lowbit(i)) {
for(int j = y; j > 0; j -= lowbit(j)) {
sum += save[i][j];
}
}
return sum;
}
void init(){
int i,j,n,m;
for(i=1;i<=1000;i++){
for(j=1;j<=1000;j++){
rigi[i^j].push_back(make_pair(i, j));
}
}
memset(save, 0, sizeof(save));
for(i=1;i<=t;i++){
scanf("%d%d",&n,&m);
in[i].ask = make_pair(n, m);
for(j=0;j<=1023;j++){
in[i].res[j] = 0;
}
}
for(i=0;i<=1023;i++){
for(j=0;j<rigi[i].size();j++){
update(rigi[i][j].first, rigi[i][j].second, 1);
}
for(j=1;j<=t;j++){
in[j].res[i] = query(in[j].ask.first, in[j].ask.second);
}
for(j=0;j<rigi[i].size();j++){
update(rigi[i][j].first, rigi[i][j].second, -1);
}
}
A[0] = 1;
A[1] = 1;
for(i=2;i<=1023;i++){
A[i] = (A[i-1]*i)%mod;
}
}
int main(){
int i,j;
scanf("%d",&t);
long long res;
init();
for(i=1;i<=t;i++){
res = 1;
for(j=0;j<=1023;j++){
res = (res*A[in[i].res[j]])%mod;
}
printf("%lld\n",res);
}
return 0;
}