D - Matrices with XOR property 二维树状数组+pair

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\n",ans[i][1024]);
    }
}

 

posted @ 2017-03-12 11:03  Heilce  阅读(178)  评论(0编辑  收藏  举报