模拟题-code

code

题意

给定一个M*N 的矩阵,矩阵中每个数都是一个 K 位 2 进制数,把矩阵每一行的数都或起来,得到 N 个数,把每一列的数都或起来,得到 M 个数,让得到的n+m个数都等于2k-1

样例

in

多组测试数据,在输入的第一行会给出测试数据组数 T 。
每组测试数据一共一行,为三个整数N,M,K。
4
1 1 31
1 10 2
2 2 1
2 3 2

out

输出每组数据一行,即答案。
1
1
7
625

 

闲扯

一共三个半小时的考试,在这题上花了俩还多

而且 竟然爆零了

而且 听人家AC的讲题没听懂

而且 听听懂的人讲题还没懂

我这种蒟蒻是不是没救了

 

最后照着AC代码模拟。。。

 

然后

如果发现有不合理的地方,欢迎指出

如果发现有不合理的地方,欢迎指出

如果发现有不合理的地方,欢迎指出

思路

因为二进制的每一位是互相独立的,只需要算出m*n的矩阵或起来是1的方案数

最后算k次方

容斥原理

 

总情况2^(n*m)

总情况中包含“一行零列”这种不合法情况
需要减去这种情况
同时总情况中也包含“零行一列”这种不合法情况
需要减去这种情况
但是减去这两项的话
“一行一列”这种情况就被减了两次
需要再加一次

同理
由于“i-1行j列”和“i行j-1列”的重复计算
使得“i行j列”的情况多减了,需要与上述运算的符号相反
即:i,j组合的符号是根据上面的计算推出来的

res:仅考虑i行j列中没有1的情况总数
C(n,i)*C(m,j)是把行列选出来
Pow(2^(n*m-i*m-j*n+i*j))是说:剩下的格子随意,当前仅考虑选出的i行j列中没有1

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define N 100005
#define LL long long
#define mod 1000000007
long long a[55];
void pre(){
    a[0]=1;
    for(int i=1;i<=50;i++){
        a[i]=a[i-1]*i%mod;
    }
}
inline void putout(long long x){
    char c[15];
    int k=0;
    if(x<0) putchar('-'),x=-x;
    do {
        c[++k]=x%10+48;
        x/=10;
    } while(x);
    while(k) putchar(c[k--]);
}
inline long long fastpow(long long now,int k){
    long long mul=now;
    long long ret=1LL;
    while(k){
        if(k%2){
            ret=ret*mul%mod;
        }
        mul=mul*mul%mod;
        k>>=1;
    }
    return ret;
}
long long C(int n,int m){
    LL ret=1LL*(a[n]*fastpow(a[m],mod-2)%mod)*
                fastpow(a[n-m],mod-2)%mod;
    return ret;
}
int main(){
    freopen("code.in","r",stdin);
    freopen("code.out","w",stdout);
    int T;
    pre();
    scanf("%d",&T);
    while(T--){
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        long long ans=0;
        for(int i=0;i<=n;i++){
            for(int j=0;j<=m;j++){
                int plus=((i+j)%2) ? -1:1;
                long long fast=fastpow(2,n*m-i*m-j*n+i*j);
                long long res=(1LL*C(n,i)*C(m,j)%mod)*fast%mod;
                ans=(ans+res*plus)%mod;
            }
        }
        ans=(ans+mod)%mod;
        ans=fastpow(ans,k);
        printf("%I64d\n",ans);
    }
    return 0;
}

 

posted @ 2018-10-25 18:39  冬猫  阅读(132)  评论(0编辑  收藏  举报