codeforces#1228E. Another Filling the Grid(容斥定理,思维)

题目链接:

https://codeforces.com/contest/1228/problem/E

题意:

给n*n的矩阵填数,使得每行和每列最小值都是1

矩阵中可以填1到$k$的数

数据范围:

$1leq n leq 250$

$1leq k leq 250$

分析: 

参考博客:https://www.cnblogs.com/scx2015noip-as-php/p/cf589e.html

先预处理出f(x)代表x*n的矩阵,每列最小值是1的填充方案数

以下讨论的方案数,列的最小值一定是1

ans=随便填-第一行没有1-第二行没有1-第三行没有1-第n行没有1+第一二行没有1+第二三行没有1......

也就是对行的方案容斥

因为第一行没有1和第二行没有1的方案可能重复了,所有多减了一些方案数

$ans = sumlimits_{i=0}^n (-1)^i C_n^i (k-1)^{ni} f(n-i)$

AC代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=250+7;
const int mod=1e9+7;
ll A[maxn],invA[maxn],f[maxn];
ll qpow(ll x,ll y){
    ll res=1;
    while(y){
        if(y&1)res=x*res%mod;
        x=x*x%mod;
        y/=2;
    }
    return res;
}
int main()
{
    int n,k;
    A[1]=invA[1]=A[0]=invA[0]=1;
    for(int i=2;i<maxn;i++){
        A[i]=A[i-1]*i%mod;
        invA[i]=invA[i-1]*qpow(i,mod-2)%mod;
    }
    scanf("%d %d",&n,&k);
    for(int i=1;i<=n;i++)
        f[i]=qpow((qpow(k,i)-qpow(k-1,i)+mod)%mod,n);
    ll res,ans=0;
    for(int i=0;i<n;i++){
        if(i%2==0)res=1;
        else res=-1;
        res=res*f[n-i];
        res=res*qpow(k-1,n*i)%mod;
        res=res*A[n]%mod*invA[i]%mod*invA[n-i]%mod;
        ans=(ans+res+mod)%mod;
    }
    printf("%lld
",ans);
    return 0;
}

  

原文地址:https://www.cnblogs.com/carcar/p/11637801.html