cf/Codeforces Gym 100548F Color (容斥原理)

题目大意:直线上给n个物品染色,一共有m种颜色,求恰好用了k种颜色的染色方案数


解析:

首先选出k种颜色,选法C(m,k), 那么对于不超过k种颜色的涂色方案数为 f[k]= k*(k-1)^(n-1) 表示第一个有k种选择,后面的全都是k-1种选择 。  这里面包含了  k=1,2,3,......k的全部情况

ps: 最开始智障了,觉得f[k]-f[k-1]不显然就是答案了吗。。nc啊。。。

ps: 明显在选出了k种颜色的条件下,f[k]为不超过k种颜色的所有方案,那么就是要减去不超过k-1种颜色的所有方案,但是k种颜色里选k-1种又有一个 C(k,k-1),所以应该减去的是C(k,k-1)*f(k-1),而显然这样f(k-2)那些又会被减掉了需要加回来,加加减减就是一眼容斥原理啦



已选出k种颜色后,那么对于最后涂了不超过i种(2<=i<=k-1)颜色的方案数为g[i]=  C(k,i)* i*(i-1)^(n-1)


所以对于选出来的k种颜色下,我们要染恰好k个颜色的合法方案数应该为ans[k]= f[k] -g[k-1] +g[k-2]-g[k-3]........ 

最后答案为 c(m,k)*ans[k] 


由于算g[i]之和时要用到一个c[k]【i】

然后最后算答案要求一个C【m】【k】

p又特别大 (1e9+7)

lucas预处理p的那种肯定不行,直接算的单case的又太慢了

注意到C几几的第二项比较小,只有k,

则可以用O(K)去算出所有的组合数,公式:c(n,k+1)=c(n,k)*(n-k)/(1+k) 

那么就预处理1到k的逆元



整体复杂度O(K)


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long  ll;
const ll p =1000000007;
ll fast_m(ll a,ll b)
{
    ll x,ans=1;
    x=a;
    while(b)
    {
        if (b&1)
            ans=(ans*x)%p;
        x=(x*x)%p;
        b/=2;
    }
    return ans;
}
ll n,m,k;

ll inv[1000000+5];
void Init_inv()
{
    for(int i = 1; i < 1e6+50; i++)
        inv[i] = fast_m(i, p - 2);
}
ll c[1000000+50];

void cal(ll n)
{
    c[0] = 1;
    for(int i = 1; i <= k; i++)
        c[i] = ((c[i - 1] * (n - i + 1) % p) * inv[i] % p) % p;
}
ll f(ll k)
{
    return k*fast_m(k-1,n-1)%p;
}
int main()
{
    Init_inv();
    int t;
    cin>>t;
    int cnt=1;
    while(t--)
    {
        scanf("%lld%lld%lld",&n,&m,&k);
        cal(k);

        ll ansk=f(k);
        for (int i=2; i<=k-1; i++)
        {
            if ((k-i)%2)   ansk=(ansk-c[i]*f(i)%p )%p;
            else ansk=(ansk+ (c[i]*f(i)) %p) %p;
        }
        cal(m);
        printf("Case #%d: %lld\n",cnt++, (c[k]*ansk%p+p)%p);
    }

    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值