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]
题解: 这个题是可以纯暴力水过的,但是我感觉要是范围再大一点就不可以了,所以还是应该会点正解的。
1、有一个非常高深的办法,就是先算出来前500个,然后再然后类似二分然后算出来后面的情况总的时间复杂度就是500*500;
2、数位dp。
3、就是我写的这个二维的树状数组,但是能想到这个解决办法的人,我认为还是很厉害的,我是实在想不到。
讲道理这个东西确实厉害。
#include<bits/stdc++.h> using namespace std; const int maxn=1e3+50; const int mod=1e9+7; long long f[2000000],c[maxn][maxn]; vector<pair<int,int> >v[maxn]; long long ans[maxn][maxn]; struct node { int a,b; }s[maxn]; void inist() { f[0]=1; for(int i=1;i<=1000000;i++) { f[i]=(f[i-1]*(i%mod)); f[i]%=mod; } } int lowbit(int x) { return x&-x; } int sum(int x,int y) { int ret = 0; for(int i = x;i > 0;i -= lowbit(i)) for(int j = y;j > 0;j -= lowbit(j)) ret += c[i][j]; return ret; } void add(int x,int y,int val) { for(int i = x;i <= 1000;i += lowbit(i)) for(int j = y;j <= 1000;j += lowbit(j)) c[i][j] += val; } int main() { int t; scanf("%d",&t); inist(); for(int i=1;i<=t;i++) scanf("%d%d",&s[i].a,&s[i].b); for(int i=1;i<=1000;i++) { for(int j=1;j<=1000;j++) { v[i^j].push_back(make_pair(i,j)); } } for(int x=0;x<=1024;x++) { int sz=v[x].size(); for(int j=0;j<sz;j++) { int a=v[x][j].first; int b=v[x][j].second; add(a,b,1); } for(int j=1;j<=t;j++) { ans[j][x]=sum(s[j].a,s[j].b); } for(int j=0;j<sz;j++) { int a=v[x][j].first; int b=v[x][j].second; add(a,b,-1); } } for(int i=1;i<=t;i++) { for(int j=0;j<=1024;j++) { if(ans[i][j]==0) ans[i][j]=ans[i][j-1]; else { if(j>=1) ans[i][j]=(f[ans[i][j]]*ans[i][j-1])%mod; else ans[i][j]=(f[ans[i][j]])%mod; } } printf("%lld ",ans[i][1024]); } }