• Perm 排列计数(bzoj 2111)


    Description

    称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案可能很大,只能输出模P以后的值

    Input

    输入文件的第一行包含两个整数 n和p,含义如上所述。

    Output

    输出文件中仅包含一个整数,表示计算1,2,⋯, ���的排列中, Magic排列的个数模 p的值。

    Sample Input

    20 23

    Sample Output

    16

    HINT

    100%的数据中,1 ≤ ��� N ≤ 106, P��� ≤ 10^9,p是一个质数。 数据有所加强

    /*
        求n个数组成小根堆的方案数。 
        设f[i]为以i为根的小根堆方案数。
        f[i]=C(sz[i]-1,sz[i*2])*f[i*2]*f[i*2+1]。 
        最神奇的是被lucas坑了一把,当n>mod时预处理就成0啦!!! 
    */
    #include<iostream>
    #include<cstdio>
    #define N 1000010
    #define lon long long
    using namespace std;
    int n,mod,hal[N],sz[N];
    lon inv[N],jc1[N],jc2[N];
    void init(){
        inv[0]=inv[1]=1;for(int i=2;i<=n;i++) inv[i]=((mod-mod/i)*inv[mod%i])%mod;
        jc1[0]=1;for(int i=1;i<=n;i++) jc1[i]=(jc1[i-1]*i)%mod;
        jc2[0]=1;for(int i=1;i<=n;i++) jc2[i]=(jc2[i-1]*inv[i])%mod;
    }
    lon C(int n,int m){
        if(n<m) return 0;
        if(n>mod||m>mod) return (C(n%mod,m%mod)*C(n/mod,m/mod))%mod;
        else return ((jc1[n]*jc2[m])%mod*jc2[n-m])%mod;
    }
    void dfs1(int x){
        sz[x]=1;
        if(x*2<=n) dfs1(x*2),sz[x]+=sz[x*2];
        if(x*2+1<=n) dfs1(x*2+1),sz[x]+=sz[x*2+1];
    }
    lon dfs2(int x){
        if(x*2>n) return 1;
        lon tot=C(sz[x]-1,sz[x*2]);
        if(x*2<=n) tot=(tot*dfs2(x*2))%mod;
        if(x*2+1<=n) tot=(tot*dfs2(x*2+1))%mod;
        return tot;
    }
    int main(){
        scanf("%d%d",&n,&mod);
        init();
        dfs1(1);
        printf("%d",dfs2(1));
        return 0;
    }
  • 相关阅读:
    springMVC-接收数据-参数绑定
    我的asp.net core目录
    我的IdentityServer目录
    win10安装mysql
    asp.net core webapi 生成导出excel
    Dapper, 批量插入,批量更新, 以及in, like
    asp.net core 依赖注入几种常见情况
    asp.net core 2.1 配置管理
    各个模式的accesstoken续期详解
    ResourceOwnerPassword模式使用数据库.
  • 原文地址:https://www.cnblogs.com/harden/p/6675746.html
Copyright © 2020-2023  润新知