zoukankan      html  css  js  c++  java
  • Codeforces 1228E. Another Filling the Grid

    传送门

    看到 $n=250$ 显然考虑 $n^3$ 的 $dp$

    设 $f[i][j]$ 表示填完前 $i$ 行,目前有 $j$ 列的最小值是 $1$ 的合法方案数

    那么对于 $f[i][j]$ ,枚举 $f[i-1][k]$ ,有 $f[i][j]=sum_{k=0}^{j}inom{n-k}{j-k}f[i-1][k](m-1)^{n-j}m^k$

    这里 $m$ 就是题目的 $k$

    $inom{n-k}{j-k}$ 是因为多出来的 $j-k$ 列 $1$ 可以任选

    $(m-1)^{n-j}$ 是保证没有 $1$ 的列不能填 $1$ ,只有 $m-1$ 种填的数

    $m^k$ 是那些原本有保证为 $1$ 的列怎么填都行

    当然剩下的那 $j-k$ 个位置显然都是 $1$ ,方案数只有 $1$

    然后这样就可以做到 $n^3 log n$ 然后发现竟然 $T$ 了,所以预处理一下 $k in [0,n],m^k$ 和 $k in [0,n],(m-1)^k$ 即可

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int mo=1e9+7,N=507;
    inline int fk(int x) { return x>=mo ? x-mo : x; }
    int n,m;
    int C[N][N],f[N][N];
    int mi[N],mi_1[N];
    int main()
    {
        n=read(),m=read();
        for(int i=0;i<=n;i++)
        {
            C[i][0]=1;
            for(int j=1;j<=i;j++)
                C[i][j]=fk(C[i-1][j]+C[i-1][j-1]);
        }
        mi[0]=mi_1[0]=1;
        for(int i=1;i<=n;i++)
        {
            mi[i]=1ll*mi[i-1]*m%mo;
            mi_1[i]=1ll*mi_1[i-1]*(m-1)%mo;
        }
        for(int j=1;j<=n;j++) f[1][j]=1ll*C[n][j]*mi_1[n-j]%mo;
        for(int i=2;i<=n;i++)
            for(int j=0;j<=n;j++)
            {
                for(int k=0;k<=j;k++)
                {
                    int x=1ll*f[i-1][k]*C[n-k][j-k]%mo;
                    int y=1ll*mi_1[n-j]*mi[k]%mo;
                    f[i][j]=fk(f[i][j]+1ll*x*y%mo);
                    if(j==k) f[i][j]=fk(f[i][j]-1ll*mi_1[n]*f[i-1][k]%mo+mo);
                }
            }
        printf("%d
    ",f[n][n]);
        return 0;
    }
    正常的做法

    但是有些神仙看完数据说:" $n$ 太小了,可以出到 $10^5$ 级别"

    所以考虑一下神仙的做法

    看到有限制的方案数,考虑容斥!

    总方案 - (一行不合法+一列不合法) + (两行不合法+两列不合法+一行一列不合法) - ......

    那么写成式子就是长这个样子:

    $sum_{i=0}^{n}sum_{j=0}^{n}(-1)^{i+j} inom{n}{i}inom{n}{j}m^{n^2-n(i+j)+ij}(m-1)^{n(i+j)-ij}$

    上面 $m^{n^2-n(i+j)+ij}$ 就是没限制的位置顺便填,$(m-1)^{n(i+j)-ij}$ 就是强制 $i$ 行 $j$ 列的格子不能填 $1$ 

    然后同样预处理一下 $m$ 和 $m-1$ 的幂次就可以做到 $n^2$

    对着这个式子继续搞:

    $sum_{i=0}^{n}sum_{j=0}^{n}(-1)^{i+j} inom{n}{i}inom{n}{j}m^{n^2-n(i+j)+ij}(m-1)^{n(i+j)-ij}$

    $sum_{i=0}^{n}(-1)^iinom{n}{i}sum_{j=0}^{n}(-1)^jinom{n}{j}m^{(n-i)(n-j)}(m-1)^{(n-i)j}(m-1)^{ni}$

    $ecause sum_{j=0}^{n}(-1)^jinom{n}{j}m^{(n-i)(n-j)}(m-1)^{(n-i)j}=(m^{n-i}-(m-1)^{n-i})^n$

    $ herefore sum_{i=0}^{n}(-1)^iinom{n}{i}(m-1)^{ni}(m^{n-i}-(m-1)^{n-i})^n$

    $sum_{i=0}^{n}(-1)^iinom{n}{i}(m^{n-i}(m-1)^i-(m-1)^n)^n$

    然后就可以 $n log n$ 解决了

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=507,mo=1e9+7;
    inline int fk(int x) { return x>=mo ? x-mo : x; }
    int n,m,Ans;
    int C[N][N],mi[N],m_1i[N];
    inline int ksm(int x,int y)
    {
        int res=1;
        while(y) { if(y&1) res=1ll*res*x%mo; x=1ll*x*x%mo; y>>=1; }
        return res;
    }
    int main()
    {
        n=read(),m=read();
        for(int i=0;i<=n;i++)
        {
            C[i][0]=1;
            for(int j=1;j<=i;j++) C[i][j]=fk(C[i-1][j]+C[i-1][j-1]);
        }
        mi[0]=m_1i[0]=1;
        for(int i=1;i<=n;i++)
        {
            mi[i]=1ll*mi[i-1]*m%mo;
            m_1i[i]=1ll*m_1i[i-1]*(m-1)%mo;
        }
        for(int i=0;i<=n;i++)
        {
            int t=1ll*C[n][i]*ksm( fk(1ll*mi[n-i]*m_1i[i]%mo - m_1i[n] +mo) , n )%mo;
            i&1 ? Ans=fk(Ans-t+mo) : Ans=fk(Ans+t);
        }
        printf("%d
    ",Ans);
        return 0;
    }
  • 相关阅读:
    ExtJS实战(3)spring
    在 Lotus Domino 7 应用程序中利用 IBM DB2 集成特性
    ExtJS实战(2)hibernate
    ExtJS实战(4)struts
    春节后找工作被面试的经历,好岗位分享给还在找工作中的软件开发爱好者们【转】
    hack专讲
    春节后面试别人的经历总结之二,好岗位分享给还在找工作中的软件开发爱好者们【转】
    asp 去除HTML格式
    创业型公司或发展中公司请不要随意给员工开空头支票~~!!!
    可展开滚动的QQ客服代码【蓝底客服中心】
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11612535.html
Copyright © 2011-2022 走看看