zoukankan      html  css  js  c++  java
  • codeforces 111D

    D. Petya and Coloring
    time limit per test
    5 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Little Petya loves counting. He wants to count the number of ways to paint a rectangular checkered board of size n × m (n rows, mcolumns) in k colors. Besides, the coloring should have the following property: for any vertical line that passes along the grid lines and divides the board in two non-empty parts the number of distinct colors in both these parts should be the same. Help Petya to count these colorings.

    Input

    The first line contains space-separated integers nm and k (1 ≤ n, m ≤ 1000, 1 ≤ k ≤ 106) — the board's vertical and horizontal sizes and the number of colors respectively.

    Output

    Print the answer to the problem. As the answer can be quite a large number, you should print it modulo 109 + 7 (1000000007).

    Examples
    input
    2 2 1
    output
    1
    input
    2 2 2
    output
    8
    input
    3 2 2
    output
    40
     

    description:
    一个矩阵有N行M列,现有k种颜色,求符合下列要求的填色方案有多少种
    要求:将矩阵竖直的切分成非空的两部分,两部分所包含的颜色数相同(只是颜色数相同,并没有要求是有相同的颜色)

    solution:
    考虑每种合法的填色方案
    假设最左边一列的颜色种类为 a ,则剩余的部分也只能有k种颜色
    此时左边的两列的颜色数必定不小于 a(多了一列),除去左边两列所剩的矩阵的颜色数必定不超过 a(少了一列)
    又因为这个矩阵符合要求,故左边两列的颜色 = 除去左边两列的 = a
    也就说明左边的第二列的颜色必定在左边第一列出现过
    如此重复下去,可以证明,除了左边第一列和右边第一列,矩阵剩余部分的颜色必定都在左边第一列(右边第一列)出现过
    不妨设左边第一列和右边第一列公共的颜色数为 b ,显然矩阵剩余部分的颜色数不超过 b ,于是中间那部分的填色方案肯定为 b ^ (n (m - 2))
    现在要去算左边第一列和右边第一列的填色方案,显然这两个都是相等的,所以现在就是考虑一个1*n的数组用正好a种颜色填充的方案数
    这个就是容斥原理就可以知道,设方案数为 F(a, n) = a ^ n - C(a, 1) * (a - 1) ^ n + C(a, 2) * (a - 2) ^ n - ...
    于是总方案数为 ∑ C(k, a) * C(a, b) * C(k - a, a - b) F(a, n) ^ 2 * b ^ (n (m - 2))

    hint:
    注意考虑a和b的枚举范围 //我就是在这里WA了很久……
    注意取模 //现在弱爆了,这个都写错
    m = 1 也要考虑

    code:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 char ch; bool ok;
     4 void read(int &x){
     5     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
     6     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
     7     if (ok) x=-x;
     8 }
     9 const int maxk=1000005;
    10 const int mod=1E9+7;
    11 int fac[maxk],inv[maxk],invfac[maxk];
    12 int n,m,k;
    13 int ksm(int a,int b){
    14     int t;
    15     for (t=1;b;b>>=1,a=1LL*a*a%mod) if (b&1) t=1LL*t*a%mod;
    16     return t;
    17 }
    18 int C(int n,int m){
    19     int res=1LL*fac[n]*invfac[m]%mod*invfac[n-m]%mod;
    20     return res;
    21 }
    22 int main(){
    23     read(n),read(m),read(k);
    24     int lim=max(n,k);
    25     fac[0]=1;
    26     for (int i=1;i<=lim;i++) fac[i]=1LL*fac[i-1]*i%mod;
    27     inv[1]=1;
    28     for (int i=2;i<=lim;i++) inv[i]=1LL*(mod-mod/i)*inv[mod%i]%mod;
    29     invfac[0]=1;
    30     for (int i=1;i<=lim;i++) invfac[i]=1LL*invfac[i-1]*inv[i]%mod;
    31     int ans=0;
    32     if (m==1){
    33         printf("%d
    ",ksm(k,n));
    34         return 0;
    35     }
    36     for (int a=1;a<=min(n,k);a++){
    37         int res=0;
    38         for (int i=0;i<a;i++){
    39             int tmp=1LL*C(a,i)*ksm(a-i,n)%mod;
    40             if (i&1) tmp=mod-tmp;
    41             res=(res+tmp)%mod;
    42         }
    43         res=1LL*res*res%mod;
    44         res=1LL*res*C(k,a)%mod;
    45         for (int b=max(2*a-k,0);b<=a;b++){
    46             ans=(ans+1LL*res*C(a,b)%mod*C(k-a,a-b)%mod*ksm(b,n*(m-2))%mod)%mod;
    47         }
    48     }
    49     printf("%d
    ",ans);
    50     return 0;
    51 }

  • 相关阅读:
    IOS越狱开发错误解决
    IOS越狱开发环境搭建
    ios越狱开发
    IOS开发常用的开源组件
    ios日期比较
    IOS RGB颜色转换
    UILabel基本用法
    ios根据字体大小设置
    第五篇 窗口管理机制之输入机制--管道过滤器模式
    第四篇 ANDROID窗口管理服务实现机制--远程代理模式
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/7834935.html
Copyright © 2011-2022 走看看