• 著名夫妻圆排列问题


    圆排列:

    问题:有n个不同的人,问围成一桌吃饭,问有多少种相对位置不同的做法;

    分析:已知线排列是n! ,那么将首位连起来就是圆排列,每旋转一个人的度数对应一个新的线排列,可选择n次,也就是说每个圆排列较线排列来说出现了n次,那么圆排列的个数为n! / n = (n-1)!.

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

    题意:问n对cp坐不相邻的方案数。

    分析:对于这类题,我们可以转化为恰好n对情侣不相邻的方案,再转化至少和不多于,再容斥;

       总的-不合法的,总的:(2n-1)!

       假设至少x对cp相邻的法案为f(x) = 2x * Cxn * (2n - 1 - x)!  表示为至少选x对情侣Cxn,每对相邻坐相对位置有2种,所以乘上2x  ,然后把选出来的2*x个人组成x个个体去算圆排列相当于减去了x个人。

       容斥:(2n-1)!-f(1)+f(2)-f(3)....f(n)

       因为内存开俩倍老是MLE,所以就从后往前算

    #include<bits/stdc++.h>
    using namespace std;
    #define pb push_back
    #define MP make_pair
    typedef long long ll;
    const int M=30000005;
    const int N=M+5;
    const int inf=0x3f3f3f3f;
    const ll INF=1e18;
    const int mod=1e9+7;
    int fac[M],facinv[M];
    int ksm(int x,int y){
        int t=1;
        while(y){
            if(y&1)
                t=(1ll*t*x)%mod;
            x=(1ll*x*x)%mod;
            y>>=1;
        }
        return t;
    }
    int inv(int x){
        return ksm(x,mod-2)%mod;
    }
    int C(int x,int y){
        if(y>x||x<0||y<0)
            return 0;
        if(y==0||x==y)
            return 1;
        return 1ll*fac[x]*1ll*facinv[y]%mod*1ll*facinv[x-y]%mod;
    
    }
    void init(int n){
        fac[0]=1;
        for(int i=1;i<=n;i++)
            fac[i]=1ll*fac[i-1]*i%mod;
        int now=n;
        facinv[now]=ksm(fac[now],mod-2);
        for(int i=now-1;i>=0;i--)
            facinv[i]=1ll*facinv[i+1]*(i+1)%mod;
    }
    
    int main(){
    
        int n;
        scanf("%d",&n);
        if(n==0||n==1)
            return printf("0"),0;
        init(n);
        int ans=0;
        for(int i = n,Pow = ksm(2,n),Fac = fac[n - 1];
            i >= 0 ;
            Pow = 1ll * Pow * facinv[2] % mod,Fac = 1ll * Fac * (2 * n - i) % mod,i--) {
            if(i&1) ans = ((1ll * ans - (1ll * C(n,i) * Pow % mod * 1ll * Fac % mod)) % mod + mod) % mod;
            else    ans = ((1ll * ans + (1ll * C(n,i) * Pow % mod * 1ll * Fac % mod)) % mod + mod) % mod;
        }
        printf("%d
    ",(ans%mod+mod)%mod);
        return 0;
    
        }
    View Code
  • 相关阅读:
    git
    RT-Thread 4.0 + STM32F407 学习笔记1
    C#串口通信及数据表格存储
    NRF52832初步使用
    ubuntu终端下快捷键之--字体放大缩小
    微信公众号开发被动回复用户消息,回复内容Content使用了" "换行符还是没有换行
    python2018年秋季调研
    python图像处理模块Pillow--Image模块
    linux查看文件命令tail的使用
    使用xadmin更新数据时,报错expected string or bytes-like object
  • 原文地址:https://www.cnblogs.com/starve/p/13723765.html
Copyright © 2020-2023  润新知