zoukankan      html  css  js  c++  java
  • UVALive-7040-Color(容斥原理)

    链接:

    https://vjudge.net/problem/UVALive-7040

    题意:

    Recently, Mr. Big recieved n owers from his fans. He wants to recolor those owers with m colors. The
    owers are put in a line. It is not allowed to color any adjacent owers with the same color. Flowers i and
    i + 1 are said to be adjacent for every i, 1 ≤ i < n. Mr. Big also wants the total number of different
    colors of the n owers being exactly k.
    Two ways are considered different if and only if there is at least one ower being colored with different
    colors

    思路:

    先C(n, k),考虑k个有(k * (k-1)^{n-1})。减掉少一个不选的有((k-1)*(k-2)^{n-1})
    其中多减掉了两个不选的要加上。
    最后:(sum_{i=1}^{k-1}(-1)^i*C_k^{k-i}*(k-i)*(k-i-1)^{n-1})

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<math.h>
    #include<vector>
    
    using namespace std;
    typedef long long LL;
    const int INF = 1e9;
    
    const int MAXN = 1e6+10;
    const int MOD = 1e9+7;
    
    LL n, m, k;
    LL F[MAXN], Inv[MAXN], Finv[MAXN];
    
    LL Pow(LL a, LL b)
    {
        LL res = 1;
        while(b>0)
        {
            if (b&1)
                res = res*a%MOD;
            a = a*a%MOD;
            b >>= 1;
        }
        return res;
    }
    
    LL GetInv(int a)
    {
        return Pow(a, MOD-2);
    }
    
    void Init()
    {
        Inv[1] = 1;
        for (int i = 2;i < MAXN;i++)
            Inv[i] = (MOD-MOD/i)*1LL*Inv[MOD%i]%MOD;
        F[0] = Finv[0] = 1;
        for (int i = 1;i < MAXN;i++)
        {
            F[i] = F[i-1]*1LL*i%MOD;
            Finv[i] = Finv[i-1]*1LL*Inv[i]%MOD;
        }
    }
    
    LL Comb(int n, int m)
    {
        if (m < 0 || m > n)
            return 0;
        return F[n]*1LL*Finv[m]%MOD*Finv[n-m]%MOD;
    }
    
    int main()
    {
        Init();
        int t, cnt = 0;
        scanf("%d", &t);
        while(t--)
        {
            scanf("%lld%lld%lld", &n, &m, &k);
            LL res = 1LL*k*Pow(k-1, n-1)%MOD;
            int flag = -1;
            for (int i = 1;i <= k-1;i++)
            {
                res = (res+1LL*flag*Comb(k, k-i)*(k-i)%MOD*Pow(k-i-1, n-1)%MOD)%MOD;
                flag = -flag;
            }
            LL temp = Finv[k];
            for (int i = 1;i <= k;i++)
            {
                temp = 1LL*temp*(m-k+i)%MOD;
            }
            res = ((1LL*res*temp)%MOD+MOD)%MOD;
            printf("Case #%d: %lld
    ", ++cnt, res);
        }
    
        return 0;
    }
    
  • 相关阅读:
    Zara带你快速入门WPF(1)---开篇
    Vue Route Building the UI back-end framework
    TDX指标的理解与改造(价格到达指标线提醒)
    Vue生命周期详解
    Vue轻松入门,一起学起来!
    NodeJs安装步骤与淘宝镜像
    使用npm安装配置vue
    JavaScript面向对象
    vim常用快捷键
    python常用命令
  • 原文地址:https://www.cnblogs.com/YDDDD/p/11809151.html
Copyright © 2011-2022 走看看