最后的晚餐(dinner)

最后的晚餐(dinner)

https://ac.nowcoder.com/acm/problem/19857

分析

一眼的数学题。因为原问题并不好做,按照正难则反,我们先考虑容斥。定义 表示至少有 对情侣坐在了一起。那么 为容斥系数。考虑单独的 如何求解。那么我们发现这是在求一个圆排列,根据 元素构成的圆排列方式为 。所以 表示 个有标号的元素的圆排列方式。最后 。注意一下空间限制,对于 要预处理。时间复杂度为

代码

#include<bits/stdc++.h>
using namespace std;
#define LL long long
int read() {
    int x = 0,f = 0;char ch = getchar();
    while(!isdigit(ch)) {if(ch=='-')f=1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return f?-x:x;
}
const int N = 30000010,P = 1e9 + 7;
int qpow(int a,int b) {
    int x = 1;
    for(;b;b>>=1,a = 1LL * a * a % P) {
        if(b & 1) x = 1LL * a * x % P;
    }
    return x;
}
int ans = 0,fac[N * 2],ifac[N];
int C(int n,int m) {return 1LL * fac[n] * 1LL * ifac[m] % P * ifac[n - m] % P;}
signed main() {
    LL n = read();
    if(n == 0 || n == 1) {printf("0\n");return 0;}
    fac[0] = 1;
    for(int i = 1;i <= n * 2;i++) {fac[i] = 1LL * fac[i-1] * i % P;}
    ifac[n] = qpow(fac[n],P - 2);
    for(int i = n - 1;i >= 0;i--) {ifac[i] = 1LL * ifac[i + 1] * (i + 1) % P;}
    for(int i = n,Pow = qpow(2,n),Fac = fac[n - 1]; i >= 0 ;  Pow = 1LL * Pow * ifac[2] % P,Fac = 1LL * Fac * (2 * n - i) % P,i--) {
        if(i&1) ans = ((1LL * ans - (1LL * C(n,i) * Pow % P * 1LL * Fac % P)) % P + P) % P;
        else    ans = ((1LL * ans + (1LL * C(n,i) * Pow % P * 1LL * Fac % P)) % P + P) % P;
        // cout << ans << endl;
        // cout << Fac << " " << Pow << endl;
    }
    printf("%d\n",(ans % P + P) % P);
    return 0;
}
数学 文章被收录于专栏

关于多项式

全部评论

相关推荐

牛客464620405号:随便投,随便找,中国经过40多年的改革开放,人才缺口和职位空缺是巨大的,中国现在属于遍地黄金的年代,属于90后和00大机遇的时代
点赞 评论 收藏
分享
吴offer选手:学到了,下次面试也放张纸在电脑上,不然老是忘记要说哪几个点
点赞 评论 收藏
分享
评论
4
3
分享

创作者周榜

更多
牛客网
牛客企业服务