nowcoder OI 周赛 最后的晚餐(dinner) 解题报告

最后的晚餐(dinner)

链接:

https://www.nowcoder.com/acm/contest/219/B

来源:牛客网

题目描述

\(\tt{**YZ}\)(已被和谐)的食堂实在是太挤辣!所以\(\tt{Apojacsleam}\)现在想邀请他的一些好友去校外吃一顿饭,并在某酒店包下了一桌饭。

\(\tt{Apojacsleam}\)和他的同学们来到酒店之后,他才发现了这些同学们其实是\(N\)\(cp\),由于要保护广大单身狗的弱小心灵(\(FF\)!),所以他不想让任意一对情侣相邻。

说明:

  • 酒店的桌子是恰好有\(2N\)个位置的圆桌。
  • 客人恰好是\(N\)\(cp\),也就是说,圆桌上没有空位。
  • 桌子的每一个位置是一样的,也就是说,如果两种方案可以通过旋转得到,那么这就可以视为相等的。
  • 现在,你需要求出,将任意一对情侣不相邻的方案数。

说明

对于\(20\%\)的数据,\(1\le N\le 5\)
对于\(30\%\)的数据,\(1\le N\le20\)
对于\(50\%\)的数据,\(1\le N\le100\)
对于\(70\%\)的数据,\(1\le N\le 200000\)
对于\(100\%\)的数据,\(1\le N\le 30000000\)


思路:容斥原理

\(f_i\)代表至少\(i\)对情侣坐相邻的方案数。

首先考虑一个小问题,\(n\)个人围成一个可以旋转的环的方案数。

可以固定第一个人,方案数就是\((n-1)!\)

那么\(f_i=fac_{2n-i-1}\times 2^i \times \binom{n}{i}\)

分别代表,捆绑法以后的方案数,情侣内部的方案数和选择情侣的可能性。

答案就是\(\sum_{i=0}^nf_i(-1)^i\)

常数写的不好。。说起来标程写的好厉害,我都没看懂。。


Code:

#include <cstdio>
#define ll long long
const ll mod=1e9+7;
const ll Inv=500000004;
const int N=3e7+10;
ll quickpow(ll d,ll k)
{
    ll f=1;
    while(k)
    {
        if(k&1) f=f*d%mod;
        d=d*d%mod;
        k>>=1;
    }
    return f;
}
ll fac,tfac=1,ans=0,inv[N],po=1;
int n;
int main()
{
    scanf("%d",&n);
    if(n==1) return puts("0"),0;
    for(ll i=1;i<=n;i++) tfac=tfac*i%mod,po=po*2%mod;

    fac=tfac*quickpow(n,mod-2)%mod;

    inv[n]=quickpow(tfac,mod-2);

    for(ll i=n-1;~i;i--) inv[i]=inv[i+1]*(i+1)%mod;

    for(ll i=n;~i;i--)
    {
        (ans+=fac*inv[i]%mod*inv[n-i]%mod*po%mod*(i&1?-1:1))%=mod;
        fac=fac*(2*n-i)%mod;
        po=po*Inv%mod;
    }
    
    ans=(ans+mod)%mod;
    ans=ans*tfac%mod;
    printf("%lld\n",ans);
    return 0;
}

2018.10.28

转载于:https://www.cnblogs.com/butterflydew/p/9867900.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值